Hi,

Does accessing a backref always have to issue SQL, even if the object to
be loaded already exists in the identity map? For example, if I have a
many-to-one lazy-loaded relationship from Master to Detail with a
backref, the statement "master.details[0].master" will issue SQL for the
'.master' backref, even though it already exists in the session. I know
I can eagerload('details.master'), but I was just wondering if there was
any way of getting the relation mechanism to check the identity map
before issuing the SQL.

Here is an example:


import sqlalchemy as sa
import sqlalchemy.orm as saorm
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

Base.metadata.bind = sa.create_engine('sqlite:///:memory')

class Master(Base):
    __tablename__ = 'master'
    id = sa.Column(sa.Integer, primary_key=True)


class Detail(Base):
    __tablename__ = 'detail'
    id = sa.Column(sa.Integer, primary_key=True)
    master_id = sa.Column(None, sa.ForeignKey(Master.id))
    master = saorm.relation(Master, backref='details')

def dbg(msg):
    print "\n######## %s ########" % msg
    
def test():
    dbg('SQLAlchemy version: %s' % sa.__version__)
    Base.metadata.create_all()
    Session = saorm.sessionmaker()
    sess = Session()

    m = Master()
    for i in range(10):
        m.details.append(Detail())
    sess.add(m)
    sess.commit()
    sess.close()

    Base.metadata.bind.echo = True
    sess = Session()
    dbg("Getting Master")
    m = sess.query(Master).first()
    dbg("Getting details")
    details = m.details
    dbg("Getting master of first detail")
    m2 = details[0].master
    assert m2 is m
    dbg("Getting master again via query.get")
    m3 = sess.query(Master).get(m.id)
    assert m3 is m2
    

if __name__ == '__main__':
    test()



And here is the output:

######## SQLAlchemy version: 0.5.5 ########

######## Getting Master ########
2009-08-03 13:17:12,445 INFO sqlalchemy.engine.base.Engine.0x...7ecL
BEGIN
2009-08-03 13:17:12,447 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT master.id AS master_id
FROM master
 LIMIT 1 OFFSET 0
2009-08-03 13:17:12,447 INFO sqlalchemy.engine.base.Engine.0x...7ecL []

######## Getting details ########
2009-08-03 13:17:12,451 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT detail.id AS detail_id, detail.master_id AS detail_master_id
FROM detail
WHERE ? = detail.master_id
2009-08-03 13:17:12,451 INFO sqlalchemy.engine.base.Engine.0x...7ecL [1]

######## Getting master of first detail ########
2009-08-03 13:17:12,456 INFO sqlalchemy.engine.base.Engine.0x...7ecL
SELECT master.id AS master_id
FROM master
WHERE master.id = ?
2009-08-03 13:17:12,457 INFO sqlalchemy.engine.base.Engine.0x...7ecL [1]

######## Getting master again via query.get ########

######## Finished ########


So "query.get" doesn't issue a query, but "master.details[0].master"
does. Is there any way of making the backref use query.get, and thereby
use the identity map?

Thanks a lot,

Simon






--~--~---------~--~----~------------~-------~--~----~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to