[sqlalchemy] Re: eagerloading polymorphic mapper

2008-01-16 Thread Michael Bayer


On Jan 16, 2008, at 2:24 AM, [EMAIL PROTECTED] wrote:

 yeahhh i know i dont see the wider sql picture...
 i may put all this as a ticket to remind.. maybe one day you'll be  
 in better
 mood (;-)



it can certainly be done but id like to at least first get eager loads  
from the *base* polymorphic mapper working...query has been steadily  
heading towards a more sophisticated and singular notion (such as, now  
you can do your query.select_from(any selectable).filter() which you  
wanted months ago) and i think theres a certain order things need to  
be done.

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread svilen

well, i tried it manualy and it works (sqlite).

here the eagerloading query:

model-description (joined_inheritance):
class A:
  name = Text()
class B(A):
  address = reference( Adress)
  nom = reference( Nomerator)
class C(A): pass


select * from A 
 left outer join B on A.db_id = B.db_id 
 left outer join C on A.db_id = C.db_id
 left outer join 
   Address as a1 on p.address_id = address.db_id
 left outer join 
   Nomerator as a2 on p.nom_id = a2.db_id 
;

or with subselects: 

select * from A 
 left outer join B on A.db_id = B.db_id 
 left outer join C on A.db_id = C.db_id
 left outer join 
   ( select * from Address ) as a1 on p.address_id = address.db_id
 left outer join 
   ( select * from Nomerator) as a2 on p.nom_id = a2.db_id 
;



also, i dont see a reason for it not to work if the (A jon B join C) 
is a polymunion - all the same, all columns will be present there, 
having None where missing.

0.4.3?

On Monday 14 January 2008 18:56:16 svilen wrote:
 On Monday 14 January 2008 18:35:40 Michael Bayer wrote:
  On Jan 14, 2008, at 11:29 AM, svilen wrote:
   On Monday 14 January 2008 17:19:14 Michael Bayer wrote:
   On Jan 14, 2008, at 8:41 AM, svilen wrote:
   i have, say, base class A, inherited by two children B and C.
   B has an attribute/relation 'address', A and C do not have
   it. So i had a query(A).eagerload( 'address') and that did
   work before r3912. But later it gives an error - mapper|A
   has no property 'address'.
   Any hint how to do it now?
  
   what kind of inheritance/mapping  from A-B ?  i cant really
   imagine any way that kind of eager load could have worked
   since the address property of B does not (and has never)
   get consulted in that case.
  
   plain joined?... hmm.
   maybe it did not really work (eagerly) but lazy-load has fired
   instead... seems that's the case.
   anyway.
   some way to accomplish such thing?
 
  no !  this the same issue with the Channel-CatalogChannel thing,

 yes i guessed it..

  your query is against A...attributes that are only on B don't
  enter into the equation here.

 this is somewhat different, my query/filter is on attributes that
 do exist in A; i only want the ORM to postprocess certain things...
 there will be 'address' column in the result-set anyway (empty or
 not), why it cannot be eagerloaded via B.address?

  But also, if youre using
  select_table, we dont yet support eager loads from a
  polymorphic-unioned mapper in any case (though we are close).

 it is not polymunion, joined_inh works via left-outer-join.

 well, no is no.

 


--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread Michael Bayer


On Jan 15, 2008, at 4:33 AM, svilen wrote:


 also, i dont see a reason for it not to work if the (A jon B join C)
 is a polymunion - all the same, all columns will be present there,
 having None where missing.

 0.4.3?


unlikely, I dont see how it could work from a generic standpoint. 
the query generates SQL based on the attributes attached to A.  if it  
had to also loop through all the attributes of B, C, D, E, F, etc. and  
attempt to have all of those add their clauses to the SQL, theyd all  
have to assume that the selectable for A even supports receiving  
their joins, etc. 
  

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread svilen

On Tuesday 15 January 2008 17:19:49 Michael Bayer wrote:
 On Jan 15, 2008, at 4:33 AM, svilen wrote:
  also, i dont see a reason for it not to work if the (A jon B join
  C) is a polymunion - all the same, all columns will be present
  there, having None where missing.
 
  0.4.3?

 unlikely, I dont see how it could work from a generic standpoint.
 the query generates SQL based on the attributes attached to A.  if
 it had to also loop through all the attributes of B, C, D, E, F,
 etc. and attempt to have all of those add their clauses to the SQL,
 theyd all have to assume that the selectable for A even supports
 receiving their joins, etc.

hmmm, specify explicitly? 
e.g. query(A).eagerload( B.address)

joined-inh via left-outer-join is enough, no need for polymunion. IMO 
this will be big plus for the ORM - eagerloading polymorphical child 
attributes - moving further away from SQL-like-looking stuff.
i dont know how the current machinery for eagerload works, but imo 
knowing your level of lookahead-design, it should not be hard to 
apply that machinery over a polymorphic mapper/query?
ciao
svilen

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread Michael Bayer


On Jan 15, 2008, at 10:49 AM, svilen wrote:


 hmmm, specify explicitly?
 e.g. query(A).eagerload( B.address)

 joined-inh via left-outer-join is enough, no need for polymunion.

uh well i supposeeagerload options dont really affect the  
traversal that way and it would take some non-trivial rearrangement  
of internals.

 IMO
 this will be big plus for the ORM - eagerloading polymorphical child
 attributes - moving further away from SQL-like-looking stuff.

we *like* SQL !  we dont want to become OQL.

 i dont know how the current machinery for eagerload works, but imo
 knowing your level of lookahead-design, it should not be hard to
 apply that machinery over a polymorphic mapper/query?


theres plenty of much higher priority issues than this one in the  
queue...considering that you can already get the results you want with  
this one using direct SQL.

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread sdobrev
 hmmm, specify explicitly?
 e.g. query(A).eagerload( B.address)

 joined-inh via left-outer-join is enough, no need for polymunion.

 i dont know how the current machinery for eagerload works, but imo
 knowing your level of lookahead-design, it should not be hard to
 apply that machinery over a polymorphic mapper/query?
 
 theres plenty of much higher priority issues than this one in the  
 queue...considering that you can already get the results you want with  
 this one using direct SQL.

right..

i've hacked something that seems to work; It's about 20 lines split in 
orm.query and orm.interfaces:
  - such special eagerloaders are requested as query.eagerload( B.address) - 
and not just the name/path
  - query-compile calling context.exec_withpath(...) iterates over all 
self.mapper properties (not only select_mapper's), plus all eagerloaders of 
above type (i.e. non-names). Thus the 4 cases are covered:
  A has address / query(B).eagerload('address') #works before
  A has address / query(A).eagerload('address') #new - did not work before
  B has address / query(B).eagerload('address') #works before
  B has address / query(A).eagerload(B.address) #new - not possible before
(in all these B inherits A via joined inheritance; A is polymorphic via 
left-outer-joins)
i'm absolutely sure that this is not the completely right thing - that's 
what i got from the machinery-src in 2 hours -  but it is something as a 
start... sure it needs correctness tests etc of the sorts.

g'night
svilen

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---

Index: orm/query.py
===
--- orm/query.py	(revision 4032)
+++ orm/query.py	(working copy)
@@ -991,10 +991,20 @@
 # give all the attached properties a chance to modify the query
 # TODO: doing this off the select_mapper.  if its the polymorphic mapper, then
 # it has no relations() on it.  should we compile those too into the query ?  (i.e. eagerloads)
-for value in self.select_mapper.iterate_properties:
+
+for value in self.mapper.iterate_properties:
+if self._only_load_props and value.key not in self._only_load_props:
+continue
+context.exec_with_path(self.mapper, value.key, value.setup, context, only_load_props=self._only_load_props)
+for (mp, key) in self._eager_loaders:
+if isinstance( key, str): continue  #plain
+value = key.property
 if self._only_load_props and value.key not in self._only_load_props:
 continue
-context.exec_with_path(self.select_mapper, value.key, value.setup, context, only_load_props=self._only_load_props)
+context.exec_with_path(self.mapper, key, value.setup, context, only_load_props=self._only_load_props)
 
 # additional entities/columns, add those to selection criterion
 for tup in self._entities:
Index: orm/interfaces.py
===
--- orm/interfaces.py	(revision 4032)
+++ orm/interfaces.py	(working copy)
@@ -594,6 +599,7 @@
 raise exceptions.ArgumentError(Can't find entity %s in Query.  Current list: %r % (str(mapper), [str(m) for m in [query.mapper] + query._entities]))
 else:
 mapper = query.mapper
+if isinstance( self.key,str):
 for token in self.key.split('.'):
 if current_path and token == current_path[1]:
 current_path = current_path[2:]
@@ -604,6 +610,16 @@
 path = build_path(mapper, prop.key, path)
 l.append(path)
 mapper = getattr(prop, 'mapper', None)
+else:
+ia = self.key
+key = ia.impl.key
+#from sqlalchemy.orm import class_mapper
+#mp  = mapper#class_mapper( ia.impl.class_) #assert mp inherits mapper?
+self.key = key
+path = build_path(mapper, ia, path)
+l.append(path)
 return l
 
 PropertyOption.logger = logging.class_logger(PropertyOption)


[sqlalchemy] Re: eagerloading polymorphic mapper

2008-01-15 Thread Michael Bayer


On Jan 15, 2008, at 5:17 PM, [EMAIL PROTECTED] wrote:

 hmmm, specify explicitly?
 e.g. query(A).eagerload( B.address)

 joined-inh via left-outer-join is enough, no need for polymunion.

 i dont know how the current machinery for eagerload works, but imo
 knowing your level of lookahead-design, it should not be hard to
 apply that machinery over a polymorphic mapper/query?

 theres plenty of much higher priority issues than this one in the
 queue...considering that you can already get the results you want  
 with
 this one using direct SQL.

 right..

 i've hacked something that seems to work; It's about 20 lines split in
 orm.query and orm.interfaces:
  - such special eagerloaders are requested as  
 query.eagerload( B.address) -
 and not just the name/path
  - query-compile calling context.exec_withpath(...) iterates over all
 self.mapper properties (not only select_mapper's), plus all  
 eagerloaders of
 above type (i.e. non-names). Thus the 4 cases are covered:
  A has address / query(B).eagerload('address') #works before
  A has address / query(A).eagerload('address') #new - did not work  
 before
  B has address / query(B).eagerload('address') #works before
  B has address / query(A).eagerload(B.address) #new - not possible  
 before
 (in all these B inherits A via joined inheritance; A is polymorphic  
 via
 left-outer-joins)
 i'm absolutely sure that this is not the completely right thing -  
 that's
 what i got from the machinery-src in 2 hours -  but it is something  
 as a
 start... sure it needs correctness tests etc of the sorts.


yeah thats the idea but it needs more work than that.  for one thing  
you might be hitting the same MappedProperty twice using that  
iteration (therefore joining twice), and also it doesn't account for  
eager loaders like eagerload(foo.bar.bat); i.e. deeper level  
properties which would need to have an adjusted path sent to them  
(or ignored in that part of the iteration).

also i can see a lot of cases where the eager loader from B is going  
to generate invalid SQL, such as joined table inheritance with no  
select_table, the query is only generated against A.  B.address   
is going to try generating an eager join against the B table which  
isnt present, and youll get some kind of mess as a result.  checking  
for this condition beforehand is bound to add lots of complexity and i  
only want to add features like these if they can be smoothly  
integrated, not lots of extra if/thens bolted on.



--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-15 Thread sdobrev

Michael Bayer wrote:
 
 On Jan 15, 2008, at 5:17 PM, [EMAIL PROTECTED] wrote:
 
 hmmm, specify explicitly?
 e.g. query(A).eagerload( B.address)

 joined-inh via left-outer-join is enough, no need for polymunion.
 i dont know how the current machinery for eagerload works, but imo
 knowing your level of lookahead-design, it should not be hard to
 apply that machinery over a polymorphic mapper/query?
 theres plenty of much higher priority issues than this one in the
 queue...considering that you can already get the results you want  
 with
 this one using direct SQL.
 right..

 i've hacked something that seems to work; It's about 20 lines split in
 orm.query and orm.interfaces:
  - such special eagerloaders are requested as  
 query.eagerload( B.address) -
 and not just the name/path
  - query-compile calling context.exec_withpath(...) iterates over all
 self.mapper properties (not only select_mapper's), plus all  
 eagerloaders of
 above type (i.e. non-names). Thus the 4 cases are covered:
  A has address / query(B).eagerload('address') #works before
  A has address / query(A).eagerload('address') #new - did not work  
 before
  B has address / query(B).eagerload('address') #works before
  B has address / query(A).eagerload(B.address) #new - not possible  
 before
 (in all these B inherits A via joined inheritance; A is polymorphic  
 via
 left-outer-joins)
 i'm absolutely sure that this is not the completely right thing -  
 that's
 what i got from the machinery-src in 2 hours -  but it is something  
 as a
 start... sure it needs correctness tests etc of the sorts.

 
 yeah thats the idea but it needs more work than that.  
 for one thing  
 you might be hitting the same MappedProperty twice using that  
 iteration (therefore joining twice), and also it doesn't account for  
 eager loaders like eagerload(foo.bar.bat); i.e. deeper level  
 properties which would need to have an adjusted path sent to them  
 (or ignored in that part of the iteration).
pure textual paths are going same (old) way; it needs some 
extra-syntax/API for multilevel descriptor-specified eagers; e.g 
eagerload( (B.foo, 'bar', C.bat ) )

 also i can see a lot of cases where the eager loader from B is going  
 to generate invalid SQL, such as joined table inheritance with no  
 select_table, the query is only generated against A.  B.address   
 is going to try generating an eager join against the B table which  
 isnt present, and youll get some kind of mess as a result.  checking  
 for this condition beforehand is bound to add lots of complexity and i  
 only want to add features like these if they can be smoothly  
 integrated, not lots of extra if/thens bolted on.
yeahhh i know i dont see the wider sql picture...
i may put all this as a ticket to remind.. maybe one day you'll be in better 
mood (;-)


--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-14 Thread Michael Bayer


On Jan 14, 2008, at 8:41 AM, svilen wrote:


 i have, say, base class A, inherited by two children B and C. B has an
 attribute/relation 'address', A and C do not have it.
 So i had a query(A).eagerload( 'address') and that did work before
 r3912. But later it gives an error - mapper|A has no
 property 'address'.
 Any hint how to do it now?


what kind of inheritance/mapping  from A-B ?  i cant really imagine  
any way that kind of eager load could have worked since the address  
property of B does not (and has never) get consulted in that case.

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-14 Thread svilen

On Monday 14 January 2008 17:19:14 Michael Bayer wrote:
 On Jan 14, 2008, at 8:41 AM, svilen wrote:
  i have, say, base class A, inherited by two children B and C. B
  has an attribute/relation 'address', A and C do not have it.
  So i had a query(A).eagerload( 'address') and that did work
  before r3912. But later it gives an error - mapper|A has no
  property 'address'.
  Any hint how to do it now?

 what kind of inheritance/mapping  from A-B ?  i cant really
 imagine any way that kind of eager load could have worked since the
 address property of B does not (and has never) get consulted in
 that case.

plain joined?... hmm. 
maybe it did not really work (eagerly) but lazy-load has fired 
instead... seems that's the case. 
anyway. 
some way to accomplish such thing?

--~--~-~--~~~---~--~~
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: eagerloading polymorphic mapper

2008-01-14 Thread Michael Bayer


On Jan 14, 2008, at 11:29 AM, svilen wrote:


 On Monday 14 January 2008 17:19:14 Michael Bayer wrote:
 On Jan 14, 2008, at 8:41 AM, svilen wrote:
 i have, say, base class A, inherited by two children B and C. B
 has an attribute/relation 'address', A and C do not have it.
 So i had a query(A).eagerload( 'address') and that did work
 before r3912. But later it gives an error - mapper|A has no
 property 'address'.
 Any hint how to do it now?

 what kind of inheritance/mapping  from A-B ?  i cant really
 imagine any way that kind of eager load could have worked since the
 address property of B does not (and has never) get consulted in
 that case.

 plain joined?... hmm.
 maybe it did not really work (eagerly) but lazy-load has fired
 instead... seems that's the case.
 anyway.
 some way to accomplish such thing?


no !  this the same issue with the Channel-CatalogChannel thing, your  
query is against A...attributes that are only on B don't enter  
into the equation here.But also, if youre using select_table, we  
dont yet support eager loads from a polymorphic-unioned mapper in any  
case (though we are close).

--~--~-~--~~~---~--~~
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
-~--~~~~--~~--~--~---