Greetings! I have a situation where I would like to be able to switch between an implicit eager load and an explicit no load of a series of related objects. I've set up a couple of mappers for the object in question (Entry in the code below), the primary mapper keeps uses a lazy load (lazy = True) and the alternate uses no load (lazy = None). However, I discovered that an object retrieved with the no load mapper, performs a lazy load when attempting to explicitly add elements to the relation list. I've included test code and the relevant log statements below:
test code: import sqlalchemy.ext.sessioncontext as sqlsessioncontext import sqlalchemy as sql import logging #logging file = logging.FileHandler(__name__+'.log') file.setLevel(logging.DEBUG) console = logging.StreamHandler() console.setLevel(logging.INFO) logging.getLogger("sqlalchemy").addHandler(console) logging.getLogger("sqlalchemy").addHandler(file) logging.getLogger("sqlalchemy").setLevel(logging.DEBUG) #create an in memory db engine = sql.create_engine("sqlite:///:memory:") metadata = sql.MetaData(engine=engine) sessionContext = sqlsessioncontext.SessionContext(lambda:sql.create_session(engine)) #class definitions class Entry(object): def __init__(self, id = None, title = None): if id: self.id = id self.title = title table = sql.Table('entry', metadata, sql.Column('id', sql.Integer(), primary_key=True), sql.Column('title', sql.String(), primary_key=True) ) class TagAssoc(object): def __init__(self, entry = None, tag = None): self.entry = entry self.tag = tag table = sql.Table('entry_to_tag', metadata, sql.Column('tag_id', sql.Integer(), sql.ForeignKey('tag.id',onupdate='CASCADE',ondelete='CASCADE'), nullable=False), sql.Column('entry_id',sql.Integer(), sql.ForeignKey('entry.id',onupdate='CASCADE',ondelete='CASCADE'), nullable=False) ) class Tag(object): def __init__(self, id = None, name = None): if id: self.id = id self.name = name table = sql.Table('tag', metadata, sql.Column('id', sql.Integer(), primary_key=True), sql.Column('name', sql.String(), primary_key=True) ) metadata.create_all() #entry mappers loading_entry_mapper = sql.mapper( Entry, Entry.table, properties = { 'tagAssocs' : sql.relation(TagAssoc, lazy = True, cascade="all, delete-orphan") } ) non_loading_entry_mapper = sql.mapper( Entry, Entry.table, properties = { 'tagAssocs' : sql.relation(TagAssoc, lazy = None, cascade="all, delete-orphan") }, non_primary = True ) tag_assoc_mapper = sql.mapper( TagAssoc, TagAssoc.table, primary_key=[TagAssoc.table.c.entry_id, TagAssoc.table.c.tag_id], [EMAIL PROTECTED] properties = { 'tag' : sql.relation(Tag, lazy=False, uselist=False), 'entry' : sql.relation(Entry,lazy=False, uselist=False) } ) tag_mapper = sql.mapper( Tag, Tag.table ) #save test data session = sessionContext.current entry1 = Entry(id = 1, title="entry1") session.save(entry1) session.flush() tag1 = Tag(id = 1, name="tag1") session.save(tag1) session.flush() assoc1 = TagAssoc(entry1, tag1) entry1.tagAssocs.append(assoc1) session.save(assoc1) session.flush() session.close() #retrieve the entry using the non-loading mapper session = sessionContext.current statement = sql.select([Entry.table]) entries = session.query(non_loading_entry_mapper).select(statement) #use a simple case: set tagAssocs to a blank list. This shouldn't cause an eager load, should it? entries[0].tagAssocs = [] The relevant log section: SELECT entry.id AS entry_id, entry.title AS entry_title FROM entry [] instances() Row (1, u'entry1') Connection <pysqlite2.dbapi2.Connection object at 0x00DECDA0> being returned to pool (Entry|entry|non-primary) _instance(): identity key (<class '__main__.Entry'>, (1, u'entry1'), None) not in session[] (Entry|entry|non-primary) _instance(): created new instance [EMAIL PROTECTED] identity (<class '__main__.Entry'>, (1, u'entry1'), None) populating [EMAIL PROTECTED] with RowProxy/id populating [EMAIL PROTECTED] with RowProxy/title #############not expected behavior for an attribute with no load.############### Executing lazy callable on [EMAIL PROTECTED] lazy load attribute tagAssocs on instance [EMAIL PROTECTED] Connection <pysqlite2.dbapi2.Connection object at 0x00DECDA0> checked out from pool SELECT anon_f75b.id AS anon_f75b_id, anon_f75b.title AS anon_f75b_title, anon_d876.id AS anon_d876_id, anon_d876.name AS anon_d876_name, entry_to_tag.entry_id AS entry_to_tag_entry_id, entry_to_tag.tag_id AS entry_to_tag_tag_id FROM entry_to_tag LEFT OUTER JOIN entry AS anon_f75b ON anon_f75b.id = entry_to_tag.entry_id LEFT OUTER JOIN tag AS anon_d876 ON anon_d876.id = entry_to_tag.tag_id WHERE ? = entry_to_tag.entry_id ORDER BY entry_to_tag.oid, anon_f75b.oid, anon_d876.oid [1] instances() Row (1, u'entry1', 1, u'tag1', 1, 1) Sooooo, what am I doing wrong? Thanks, Cory --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---