[sqlalchemy] Re: ForeignKey + schema

2007-09-14 Thread Neil Blakey-Milner

On 9/13/07, Rick Morrison [EMAIL PROTECTED] wrote:
 SA 0.3* doesn't seem to handle relationships between tables in different
 schemas very well:  it seems to think that

   schema.A - public.B

is:

   schema.A - schema.B

 and even specifying primaryjoin= in the mapper won't help it. There seems
 to be no directive to say use the default / primary schema

 (I'm using MSSQL, but I've seen very similar q's regarding both PG and
 Oracle, so I suspect it's not a db-specific issue)


 Just curious if there's been any work in this area on 0.4 in this area? I've
 been avoiding jumping in to 0.4 so far, but this could be the issue that
 gives me the push.

I'm not sure about creation, but I've not had any problems using
cross-schema foreign keys, relations, joins and so forth using
SQLAlchemy 0.3 and PostgreSQL.

We're using Elixir (and I had to fix a bug in Elixir's relation
management for it to pass things through to SQLAlchemy properly).

Neil
-- 
Neil Blakey-Milner
http://nxsy.org/
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: new Engine document

2007-07-07 Thread Neil Blakey-Milner

On 7/6/07, Michael Bayer [EMAIL PROTECTED] wrote:
 I just wrote this but haven't had time to carefully proof it...if
 people have corrections / comments let me know.

I think this is a lot easier to understand - thanks and well done.

Neil
-- 
Neil Blakey-Milner
http://nxsy.org/
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: PROPOSAL: whack query.select(), selectfirst(), selectone(), select_by(), selectfirst_by(), selectone_by(), get_by(), auto-join feature

2007-06-04 Thread Neil Blakey-Milner

On 6/3/07, Michael Bayer [EMAIL PROTECTED] wrote:
 - filter_by() would gain a new positional argument, which is
 optional, which is either a string or list of strings indicating
 property names, indicating a join path.  when this argument is
 present, a self-contained join among those mapped properties will be
 generated, and the keyword criterion of the filter_by() would be
 expressed against the endpoint of that join.  by self-contained, i
 mean that the tables used in the join will be *aliased* anonymously,
 so that different filter_by()s which specify join paths that overlap
 can be used together.  the existing behavior of being able to say
 query.join(['x', 'y', 'z']).filter_by(**kwargs) remains as well (but
 is different in that it doesnt create aliases).

...

 - the new positional argument of filter_by() is based on Gaetan's
 idea, as well as some light that was shed on the IRC channel.  it
 looks like this:

session.query(User).filter_by(['orders', 'items', 'keywords'],
 keyword_name='foo').filter_by(['orders', 'items'],
 item_price=49.50).list()

 above, we have created two joins from the users table, one of which
 joins from 'orders' to 'items' to 'keywords', and the other from
 'orders' to 'items'.  the two sets of joins are constructed using
 anonymous aliases, so that you get all users who have purchased an
 item that has the 'foo' keyword, and have also purchased an item that
 costs 49.50.  the two paths across 'orders' and 'items' are isolated
 from each other.

 if aliases were not used above, the redundant 'orders' and 'items'
 tables would converge into one FROM clause each in the final
 statement since thats the behavior of select(), but then the
 semantics of the query would then be all users who purchased items
 that cost 49.50 and also have the 'foo' keyword.

 the above capability is currently available by constructing your own
 Alias object and building join criterion manually.  But it was
 pointed out on IRC that the Django ORM constructs filtering queries
 using aliases as above.  for a lot of cases the approach saves a lot
 of lines of code spent creating manual aliases.

Hi there,

I like where things are going, but I think I should clarify how the
Django ORM does things to my knowledge.

The filter method in the Django ORM only supports keyword args a la
filter_by.  Every query is based off a mapped object (like Post).
Each filter can access other tables' columns via the relations, using
a construct like:

.filter(jobtitle__content__txt__icontains = keyword,
domain__str__content__txt__icontains = keyword)

Both jobtitle and domain__str (the domain relation and then the str
relation) are of a mapped object Strids type, which maps to the strids
table.  This has a relation content to a table with contains the
actual text to use for the current locale.

(__icontains is there to perform a LIKE '%keyword%', since there's no
ClauseElement equivalent.  I'm not suggesting supporting that.)

The joined tables are aliased as the path from the base object.  In
this case, the jobtitle join is:

INNER JOIN strids AS positionprofiles__jobtitle ON
positionprofiles.jobtitleid = positionprofiles__jobtitle.id

The domain__str__content join is:

INNER JOIN dimensions AS positionprofiles__domain ON
positionprofiles.domainid = positionprofiles__domain.id INNER
JOIN strids AS positionprofiles__domain__str ON
positionprofiles__domain.strid =
positionprofiles__domain__str.id INNER JOIN content AS
positionprofiles__domain__str__content ON
positionprofiles__domain__str.id =
positionprofiles__domain__str__content.strid

ie, it joins on domain, then str, then content, giving each one an
alias based on the path from the mapped object.

I'm a little worried that using anonymous aliases will make some
queries impossible.  For example, if you want to list all purchases of
product type B made by a manufacturer with a particular discount
agreement, since one would require a filter_by(['product', 'store'],
...) and the other will require a filter_by(['product', 'type'], ...).
 In the Django ORM, since the path to 'product' is the same, it's the
same join.

Not being able to rejoin on the same path may make certain kinds of
query building impossible.  Then again, using anonymous aliases for
each kind can solve different types of problems that can't be done
without them.

I think the principle of least astonishment would be to not have a new
join for the exact same path.  But, given enough documentation, one
can avoid astonishment.

I hope this made the situation clearer, and not more confusing.

Neil
-- 
Neil Blakey-Milner
http://nxsy.org/
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group

[sqlalchemy] Re: PROPOSAL: whack query.select(), selectfirst(), selectone(), select_by(), selectfirst_by(), selectone_by(), get_by(), auto-join feature

2007-06-04 Thread Neil Blakey-Milner

On 6/4/07, Michael Bayer [EMAIL PROTECTED] wrote:
 anyway, the filter on product/store and product/type example you just
 mention presents a third scenario, which I wouldnt consider to fall
 under the filter_by([attributes]) functionality, it would fall under
 the regular join() call which creates joins *without* aliasing.  but,
 its not supported by the current attribute-joining functionality,
 because it asks to generate two joins from a common joinpoint that is
 *not* the root.  the two ideas with regards to join() are the current
 way (join() moves the joinpoint which then never recedes) and the
 newer way (join() starts from the beginning each time).

 I just tried out an example of rejoining from the middle with the
 0.4 code, with a mapping of User-Order-Keywords, Items

 create_session().query(User).join(['orders', 'items']).filter_by
 (id=5).join(['orders','keywords']).filter_by(id=7).list()

 and I got this:

 SELECT users.id AS users_id \nFROM users JOIN orders ON users.id =
 orders.user_id JOIN items ON orders.id = items.order_id JOIN orders
 ON users.id = orders.user_id JOIN keywords ON orders.id =
 keywords.order_id \nWHERE ((items.id = ?) AND (keywords.id = ?))
 ORDER BY users.oid

 which is wrong, it joined on 'orders' twice (throws SQL error).  but
 it seems like if join() were made a little smarter to see that
 'orders' was already in there, which is pretty much required here
 since throwing an error is the least desireable option, youd get:

 SELECT users.id AS users_id \nFROM users JOIN orders ON users.id =
 orders.user_id JOIN items ON orders.id = items.order_id JOIN keywords
 ON orders.id = keywords.order_id \nWHERE ((items.id = ?) AND
 (keywords.id = ?)) ORDER BY users.oid

 where you can see the JOIN keywords is joining against the previous
 'orders' table.  I think that would work here and would be the
 approach for that scenario.

Great!  That's basically what I was trying to say.  Sorry that I can't
convey it in a more useful form.

What do you think of me putting up the full pathological-case code
from Django ORM and SQLAlchemy on the SQLAlchemy wiki, and maybe see
if there are improvements to be found for that as well (since it uses
ILIKE and not equality and a bunch of AND and OR statements, the new
filter_by improvements can't be used for it).  Just need to whittle it
down to the bare minimum in terms of tables and code first.

A bunch of real-life queries and the best code to achieve them would
be invaluable on the wiki.  Then, when changes to the API are
discussed, the examples can serve as a baseline for the types of
things that are being made easier or harder.

Neil
-- 
Neil Blakey-Milner
http://nxsy.org/
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---