excellent test case ! heres the bug more directly: from sqlalchemy import *
import logging logging.basicConfig() logging.getLogger('sqlalchemy.orm.unitofwork').setLevel(logging.DEBUG) logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) meta = BoundMetaData('sqlite://') a = Table('a', meta, Column('id', Integer, primary_key=True), Column('data', String(30)), Column('cid', Integer, ForeignKey('c.id')), ) b = Table('b', meta, Column('id', Integer, ForeignKey("a.id"), primary_key=True), Column('data', String(30)), ) c = Table('c', meta, Column('id', Integer, primary_key=True), Column('data', String(30)), Column('aid', Integer, ForeignKey('a.id', use_alter=True, name="foo")), ) meta.create_all() class A(object):pass class B(A):pass class C(object):pass mapper(A, a, properties={ 'cs':relation(C, primaryjoin=a.c.cid==c.c.id) }) mapper(B, b, inherits=A, inherit_condition=b.c.id==a.c.id, properties={ }) mapper(C, c, properties={ 'arel':relation(A, primaryjoin=a.c.id==c.c.aid) }) sess = create_session() bobj = B() sess.save(bobj) cobj = C() sess.save(cobj) sess.flush() i already knew what the change has to be, i just really needed to see how the error could occur. fix will be up soon. On Mar 20, 2007, at 7:03 AM, svilen wrote: > here. There are 2 paths in the dependency-graph, and if it chooses one > of them, it goes wrong. > > The testcase sometimes runs, sometimes not - changing anything (e.g. > cmdline params) may change the hash-strategy (hence the choice) - so > try many times. > > one dump is the ok-one, the other is error one. > >> yeah sorry I can conceive of a potential pattern that would raise >> this issue but im not able to create a mapping/scenario that >> illustrates it. see if you can get me something on this. >> >> On Mar 19, 2007, at 6:49 AM, svilen wrote: >>>> Michael Bayer wrote: >>>>> So you can take the post_update out and update to rev 2424. >>> >>> i have a problem with this 2424, before that was ok. >>> As i can't separate a short case now, here the conditions: >>> >>> multi-table-inheritance, polymorphic. Nothing else too fancy. >>> table_Entity has primary db_id, hand-made/sequence obj_id and >>> other data; >>> While populating the database: >>> ... >>> * SA: INFO INSERT INTO "Entity" (disabled, obj_id, atype) VALUES >>> (?, ?, ?) >>> * SA: INFO [0, 1, 'Person'] >>> * SA: INFO INSERT INTO "Person" (name_id, db_id) VALUES (?, ?, ) >>> * SA: INFO [2, 1] >>> >>> and now 2423 does: >>> * SA: INFO COMMIT >>> >>> while 2424 does: >>> * SA: INFO INSERT INTO "Entity" (disabled, obj_id, db_id, atype) >>> VALUES (?, ?, ?, ?) >>> * SA: INFO [0, 1, 1, 'Person'] >>> * SA: INFO ROLLBACK >>> >>> >>> for whatever reason it decides that the same object is dirty AND >>> new, and attempts to reinsert it once more. >>> Any idea? do u want logs? >> > > > > > * SA: DEBUG Dependent tuples: > (Name->Entity) > (Passport->Entity) > (Address->Entity) > (Entity->Address) > * SA: DEBUG Dependency sort: > Mapper|Name|Name > Mapper|Passport|Passport > Mapper|Address|Address (cycles: [Mapper|Address|Address, Mapper| > Entity|Entity]) > > * SA: INFO Task dump: > > UOWTask(<address1>, Name/Name/None) (save/update phase) > |- Save Name(<address2>) > | |- Process Person(<address3>).ime > | > |- UOWTask(<address4>, Passport/Passport/None) (save/update phase) > | | |- Process Person(<address3>).passport > | | > | |- UOWTask(<address5>, Address/Address/None) (contains > cyclical sub-tasks) (save/update phase) > | | |- Save (placeholder) > | | | > | | |- UOWTask(<address5>-><address6>, Person/Person/None) > (save/update phase) > | | | |- Save Person(<address3>) > | | | |---- > | | | > | | | > | | |- UOWTask(<address7>, Entity/Entity/None) (save/update > phase) > | | | |- Save Person(<address3>) > | | | |- (empty task) > | | | > | | |---- > | | > | |---- > | > | > |- UOWTask(<address4>, Passport/Passport/None) (delete phase) > | | > | |- UOWTask(<address5>, Address/Address/None) (contains > cyclical sub-tasks) (delete phase) > | | | > | | |- UOWTask(<address7>, Entity/Entity/None) (delete phase) > | | | |- (empty task) > | | | > | | | > | | |- UOWTask(<address5>-><address6>, Person/Person/None) > (delete phase) > | | | |---- > | | | > | | |---- > | | > | |---- > | > |---- > > > * SA: DEBUG (Name|Name) save_obj() start, batched > * SA: INFO BEGIN > * SA: DEBUG (Name|Name) save_obj() table 'Name' instance > Name@<address2> identity (<class 'base.Name'>, (None,), None) > * SA: INFO INSERT INTO "Name" (ime) VALUES (?) > * SA: INFO ['Person0'] > * SA: DEBUG execute() instances: Name@<address2>(Name.db_id)- > >Person@<address3>(Person.ime_id) ('1') > * SA: DEBUG (Passport|Passport) save_obj() start, batched > * SA: DEBUG (Address|Address) save_obj() start, batched > * SA: DEBUG (Person|Person) save_obj() start, batched > * SA: DEBUG (Person|Person) save_obj() table 'Entity' instance > Person@<address3> identity (<class 'models.Person'>, (None,), None) > * SA: DEBUG (Person|Person) Using polymorphic identity 'Person' for > insert column 'atype' > * SA: INFO INSERT INTO "Entity" (disabled, time_trans, time_valid, > atype) VALUES (?, ?, ?, ?) > * SA: INFO [0, None, None, 'Person'] > * SA: DEBUG execute() instances: Person@<address3>(Entity.db_id)- > >Person@<address3>(Person.db_id) ('1') > * SA: DEBUG (Person|Person) save_obj() table 'Person' instance > Person@<address3> identity (<class 'models.Person'>, (1,), None) > * SA: INFO INSERT INTO "Person" (ime_id, vazrast, address_id, egn, > passport_id, snimka, db_id) VALUES (?, ?, ?, ?, ?, ?, ?) > * SA: INFO [1, 10, None, '', None, None, 1] > * SA: DEBUG execute() instances: Person@<address3>(Entity.db_id)- > >Person@<address3>(Person.db_id) ('1') > * SA: DEBUG (Entity|Entity) save_obj() start, batched > * SA: DEBUG (Entity|Entity) save_obj() table 'Entity' instance > Person@<address3> identity (<class 'models.Person'>, (1,), None) > * SA: DEBUG (Entity|Entity) Using polymorphic identity 'Person' for > insert column 'atype' > * SA: INFO INSERT INTO "Entity" (disabled, time_trans, time_valid, > db_id, atype) VALUES (?, ?, ?, ?, ?) > * SA: INFO [0, None, None, 1, 'Person'] > * SA: INFO ROLLBACK > > * SA: DEBUG Dependent tuples: > (Name->Entity) > (Passport->Entity) > (Address->Entity) > (Entity->Address) > * SA: DEBUG Dependency sort: > Mapper|Name|Name > Mapper|Passport|Passport > Mapper|Entity|Entity (cycles: [Mapper|Entity|Entity, Mapper| > Address|Address]) > > * SA: INFO Task dump: > > UOWTask(<address1>, Name/Name/None) (save/update phase) > |- Save Name(<address2>) > | |- Process Person(<address3>).ime > | > |- UOWTask(<address4>, Passport/Passport/None) (save/update phase) > | | |- Process Person(<address3>).passport > | | > | |- UOWTask(<address5>, Entity/Entity/None) (contains > cyclical sub-tasks) (save/update phase) > | | |- Save (placeholder) > | | | > | | |- UOWTask(<address5>-><address6>, Person/Person/None) > (save/update phase) > | | | |- Save Person(<address3>) > | | | |---- > | | | > | | | > | | |- UOWTask(<address7>, Address/Address/None) (save/ > update phase) > | | | | |- Process Person(<address3>).address > | | | |---- > | | | > | | |---- > | | > | |---- > | > | > |- UOWTask(<address4>, Passport/Passport/None) (delete phase) > | | > | |- UOWTask(<address5>, Entity/Entity/None) (contains > cyclical sub-tasks) (delete phase) > | | | > | | |- UOWTask(<address7>, Address/Address/None) (delete phase) > | | | |---- > | | | > | | | > | | |- UOWTask(<address5>-><address6>, Person/Person/None) > (delete phase) > | | | |---- > | | | > | | |---- > | | > | |---- > | > |---- > > > * SA: DEBUG (Name|Name) save_obj() start, batched > * SA: INFO BEGIN > * SA: DEBUG (Name|Name) save_obj() table 'Name' instance > Name@<address2> identity (<class 'base.Name'>, (None,), None) > * SA: INFO INSERT INTO "Name" (ime) VALUES (?) > * SA: INFO ['Person0'] > * SA: DEBUG execute() instances: Name@<address2>(Name.db_id)- > >Person@<address3>(Person.ime_id) ('1') > * SA: DEBUG (Passport|Passport) save_obj() start, batched > * SA: DEBUG (Entity|Entity) save_obj() start, batched > * SA: DEBUG (Person|Person) save_obj() start, batched > * SA: DEBUG (Person|Person) save_obj() table 'Entity' instance > Person@<address3> identity (<class 'models.Person'>, (None,), None) > * SA: DEBUG (Person|Person) Using polymorphic identity 'Person' for > insert column 'atype' > * SA: INFO INSERT INTO "Entity" (disabled, time_trans, time_valid, > atype) VALUES (?, ?, ?, ?) > * SA: INFO [0, None, None, 'Person'] > * SA: DEBUG execute() instances: Person@<address3>(Entity.db_id)- > >Person@<address3>(Person.db_id) ('1') > * SA: DEBUG (Person|Person) save_obj() table 'Person' instance > Person@<address3> identity (<class 'models.Person'>, (1,), None) > * SA: INFO INSERT INTO "Person" (ime_id, vazrast, address_id, egn, > passport_id, snimka, db_id) VALUES (?, ?, ?, ?, ?, ?, ?) > * SA: INFO [1, 10, None, '', None, None, 1] > * SA: DEBUG execute() instances: Person@<address3>(Entity.db_id)- > >Person@<address3>(Person.db_id) ('1') > * SA: DEBUG (Address|Address) save_obj() start, batched > * SA: DEBUG (Address|Address) delete_obj() start > * SA: DEBUG (Person|Person) delete_obj() start > * SA: DEBUG (Entity|Entity) delete_obj() start > * SA: DEBUG (Passport|Passport) delete_obj() start > * SA: DEBUG (Name|Name) delete_obj() start > * SA: INFO Execute Complete > * SA: INFO COMMIT > <uow.py> --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---