- some deeper error checking when compiling relations, to detect an ambiguous "primaryjoin"
in the case that both sides of the relationship have foreign key references in the primary
join condition
+ - fixed bug where delete-orphan basically didn't work with many-to-many relationships [ticket:427],
+ backref presence generally hid the symptom
- added a mutex to the mapper compilation step. ive been reluctant to add any kind
of threading anything to SA but this is one spot that its its really needed since mappers
are typically "global", and while their state does not change during normal operation, the
connection.execute(statement, secondary_insert)
def preprocess_dependencies(self, task, deplist, uowcommit, delete = False):
- pass
+ #print self.mapper.mapped_table.name + " " + self.key + " " + repr(len(deplist)) + " preprocess_dep isdelete " + repr(delete) + " direction " + repr(self.direction)
+ if not delete:
+ for obj in deplist:
+ childlist = self.get_object_dependencies(obj, uowcommit, passive=True)
+ if childlist is not None:
+ for child in childlist.deleted_items():
+ if self.cascade.delete_orphan and childlist.hasparent(child) is False:
+ uowcommit.register_object(child, isdelete=True)
+ for c in self.mapper.cascade_iterator('delete', child):
+ uowcommit.register_object(c, isdelete=True)
def _synchronize(self, obj, child, associationrow, clearkeys):
dest = associationrow
source = None
def tearDownAll(self):
metadata.drop_all()
- @testbase.supported('')
+
def testdeleteorphan(self):
class A(object):
def __init__(self, data):
self.data = data
mapper(A, a, properties={
- # if no backref here, delete-orphan fails
+ # if no backref here, delete-orphan failed until [ticket:427] was fixed
'bs':relation(B, secondary=atob, cascade="all, delete-orphan")
})
mapper(B, b)
assert atob.count().scalar() ==0
assert b.count().scalar() == 0
assert a.count().scalar() == 1
+
+ def testcascadedelete(self):
+ class A(object):
+ def __init__(self, data):
+ self.data = data
+ class B(object):
+ def __init__(self, data):
+ self.data = data
+ mapper(A, a, properties={
+ 'bs':relation(B, secondary=atob, cascade="all, delete-orphan")
+ })
+ mapper(B, b)
+
+ sess = create_session()
+ a1 = A('a1')
+ b1 = B('b1')
+ a1.bs.append(b1)
+ sess.save(a1)
+ sess.flush()
+
+ sess.delete(a1)
+ sess.flush()
+ assert atob.count().scalar() ==0
+ assert b.count().scalar() == 0
+ assert a.count().scalar() == 0
if __name__ == "__main__":
testbase.main()