Michael Bayer ha scritto:
> 
> On Jan 29, 2007, at 11:30 AM, Manlio Perillo wrote:
> 
>>
>> The problem is that sometimes (at random, but I'm not sure),  
>> SQLAlchemy
>> wants to use the lazy loader for comments, when I do session.load 
>> (Derived).
>>
> 
> thats sometimes due to an "eager degrade".  eager loading will  
> generally not issue its LEFT OUTER JOIN if constructing the query  
> means it will loop back to the originating table in one query...it  
> will stop at the point before it gets there.   this kind of thing  
> actually happens a lot.  this can occur when using backrefs...if you  
> have A and B with eager refs to each other, and you load an A with  
> its B's, hitting the "A" collection on each "B" will incur as a lazy  
> load...since the eager loader isnt going to eager load A->B->A->B->A...
> 
> but im not sure if thats whats happening here.  maybe something up  
> with load(), id guess if the instance is already in the session  
> maybe.  it would help if you could show me more fully what youre doing.
> from sqlalchemy import *




Here is (after a month!) the code that reproduces the problem:


db = create_engine('postgres://manlio:[EMAIL PROTECTED]/test', echo=True)
metadata = BoundMetaData(db)

base = Table(
     'base', metadata,
     Column('uid', String, primary_key=True),
     Column('x', String)
     )

derived = Table(
     'derived', metadata,
     Column('uid', String, ForeignKey(base.c.uid), primary_key=True),
     Column('y', String)
     )

derivedII = Table(
     'derivedII', metadata,
     Column('uid', String, ForeignKey(base.c.uid), primary_key=True),
     Column('x', String)
     )

comments = Table(
     'comments', metadata,
     Column('id', Integer, primary_key=True),
     Column('uid', String, ForeignKey(base.c.uid)),
     Column('comment', String)
     )


class Base(object):
     def __init__(self, uid, x):
         self.uid = uid
         self.x = x

class Derived(Base):
     def __init__(self, uid, x, y):
         self.uid = uid
         self.x = x
         self.y = y

class DerivedII(Base):
     def __init__(self, uid, x, z):
         self.uid = uid
         self.x = x
         self.z = z

class Comment(object):
     def __init__(self, uid, comment):
         self.uid = uid
         self.comment = comment


commentMapper = mapper(Comment, comments)

baseMapper = mapper(
     Base, base,
         properties={
         'comments': relation(
             Comment, lazy=False, cascade='all, delete-orphan'
             )
         }
     )

derivedMapper = mapper(Derived, derived, inherits=baseMapper)
derivedIIMapper = mapper(DerivedII, derivedII, inherits=baseMapper)


def transact(f):
     def _wrap(*args, **kwargs):
         def _job(conn, *args, **kwargs):
             sess = create_session(bind_to=db)

             try:
                 ret = f(conn, sess, *args, **kwargs)
                 sess.flush()
                 sess.close()

                 return ret
             except:
                 sess.close()
                 raise

         return db.transaction(_job, None, *args, **kwargs)

     _wrap.__name__ = f.__name__
     return _wrap


@transact
def create(conn, sess, klass, id, *args):
     o = klass(id, *args)
     o.comments = [Comment(id, 'comment')]
     sess.save(o)

@transact
def load(conn, sess, klass, id):
     return sess.load(klass, id)

@transact
def view(conn, sess, o):
     print o.x
     print [c.comment for c in o.comments]


metadata.create_all()
try:
     create(Derived, 1, 'x', 'y')
     create(DerivedII, 2, 'xx', 'z')

     o = load(Derived, 1)
     view(o)

     o = load(DerivedII, 2)
     view(o)
finally:
     metadata.drop_all()



The problem is with the access to the comments attribute from two 
separate mapper that inherits from a common base mapper.



P.S.
Just to know: is the transact decorator implementation the best way to 
run a session inside a transaction?



Thanks and regards   Manlio Perillo

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

Reply via email to