On 9 okt, 17:39, Michael Bayer <[email protected]> wrote: > On Oct 9, 2010, at 7:02 AM, Berteun wrote: > I will start off by saying that the labeling applied to the NamedTuple > returned by Query was not originally intended to be a general purpose method > of targeting columns in the result. That approach doesn't work for non > trivial cases, as the ORM is put into many positions where the simple > behavior of "non-name-mangling" produces ambiguous results: > > print session.query(Foo.spam, Bar.spam).all()[0].keys() > ['spam', 'spam'] > > It is intended that if you really need certain labels, you'd apply them: > > print session.query(Foo.spam.label('fs'), > Bar.spam.label('bs')).all()[0].keys() > > The "auto" labeling case is currently inconsistent: > > print session.query(Foo.spam, Bar.spam).from_self().all()[0].keys() > > SELECT anon_1.foo_spam AS anon_1_foo_spam, anon_1.bar_spam AS > anon_1_bar_spam > FROM (SELECT foo.spam AS foo_spam, bar.spam AS bar_spam > FROM foo, bar) AS anon_1 > [u'foo_spam', u'bar_spam'] > > Because, if the simple ambiguous case gives you ambiguous labels, 'spam', > 'spam', we're not gaining anything by using the "unambiguous" labels in the > subquery case. In the case of an anonymous alias can produce the > non-targetetable names you've seen: > > qa = session.query(aliased(Foo).spam) > print qa.from_self().all()[0].keys() > > SELECT anon_1.foo_1_spam AS anon_1_foo_1_spam > FROM (SELECT foo_1.spam AS foo_1_spam > FROM foo AS foo_1) AS anon_1 > [u'%(19451760 foo)s_spam'] > > The "non-targetable" names, when used in the expression language, are > intended to be targeted by Column objects in the result row, not the string > name which is externally meaningless when anonymous aliases are used. But > the Query's NamedTuple doesn't provide column-based lookups and it probably > shouldn't, since the ORM is supposed to be presenting an interface that is > above the level of result-set concepts. > > Ticket #1942 is added to propagate the simple names outwards in any "select > from self" type of situation, which includes UNION. It can't go in 0.6, has > to wait until 0.7, since it produces backwards incompatible results (its very > likely people are targeting columns in a query tuple using "foo_spam", > "bar_spam", since those are the names they're getting). > UNION will work if you add labels to the first selectable: > > qa = session.query(Foo.spam.label('spam')) > qb = session.query(Bar.spam) > > print qa.union(qb).all()[0].keys()
Thank you for your extensive answer. It helped my understanding a lot. > That's a bug and is addressed by ticket #1943 which includes a patch, and it > would be extremely helpful if you could run this patch through your own tests > before we commit it. http://www.sqlalchemy.org/trac/ticket/1943 I can do that testing at the start of next week, and I'll report back on it. Again many thanks. -Berteun -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to [email protected]. 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.
