Hello; Does anyone know what the behavior for the before_update and before_insert methods of a mapper that is extended should be? From the code below, if i add a child object to an item being saved during a before_insert that has a mapper extension it is not saved, but is if session.save() is subsequently called? However changes made to the core attributes are saved, just not list items. Is that the expected behavior? If so is there an earlier event to catch and do an equivalent?
I posted the code online if it is too hard to read here: http://demisauce.googlecode.com/svn/trunk/projects/demisauce/trunk/demisauce/tests/versionable.py Thanks Aaron """ Test of Versionable using extensions Why does the before_update or before_insert not cause the items added to the lists to save? If you call save twice they do? """ from sqlalchemy import * from sqlalchemy.orm import * metadata = MetaData('sqlite://') ####### class VersionExt(MapperExtension): """will update changes""" def before_update(self, mapper, connection, instance): instance._doversion() return EXT_CONTINUE def before_insert(self, mapper, connection, instance): instance._doversion() return EXT_CONTINUE version_table = Table("version", metadata, Column("id", Integer, primary_key=True), Column('assoc_id', None, ForeignKey('version_associations.assoc_id')), Column("whatchanged", String(255), nullable=False), Column("version", Integer), ) ## association table version_associations_table = Table("version_associations", metadata, Column('assoc_id', Integer, primary_key=True), Column('type', String(50), nullable=False), Column('version', Integer, default=0), ) class Version(object): def __init__(self, chg): self.whatchanged = chg member = property(lambda self: getattr(self.association, '_backref_ %s' % self.association.type)) class VersionAssoc(object): def __init__(self, name): self.type = name def versionable(cls, name, uselist=True): """versionable 'interface'. """ mapper = class_mapper(cls) table = mapper.local_table mapper.add_property('version_rel', relation(VersionAssoc, backref='_backref_%s' % table.name)) if uselist: # list based property decorator def get(self): if self.version_rel is None: self.version_rel = VersionAssoc(table.name) return self.version_rel.versions setattr(cls, name, property(get)) else: # scalar based property decorator def get(self): return self.version_rel.versions[0] def set(self, value): if self.version_rel is None: self.version_rel = VersionAssoc(table.name) self.version_rel.versions = [value] setattr(cls, name, property(get, set)) mapper(Version, version_table) mapper(VersionAssoc, version_associations_table, properties={ 'versions':relation(Version, backref='association'), }) ###### # sample # 1, users users = Table("users", metadata, Column('id', Integer, primary_key=True), Column('name', String(50), nullable=False), # this column ties the users table into the change association Column('assoc_id', None, ForeignKey('version_associations.assoc_id')) ) class User(object): def _doversion(self): v1 = Version('what was changed?') self.versions.append(v1) v1.version = 1 mapper(User, users, extension=VersionExt()) versionable(User, 'versions', uselist=True) ###### # use it ! metadata.create_all() u1 = User() u1.name = 'bob' sess = create_session() sess.save(u1) sess.flush() # uncommenting these saves causes the versions to now be saved? # sess.save(u1) # sess.flush() sess.clear() # query objects, get their versions bob = sess.query(User).filter_by(name='bob').first() print [v.whatchanged for v in bob.versions] if bob.versions: print 'bob changed: %s ct = %s ' % (bob.versions[0].whatchanged, len(bob.versions)) else: print 'no versions' --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---