hey Barry - again, can you please attach a working test case for this one ? attached is mine, which tests this exact operation for four diferent kinds of relation()s - one-to-many and many to many, with and without delete cascade on the relation. passes for 0.3 (including 0.3.10) and 0.4. |
from sqlalchemy import * from sqlalchemy.orm import * def test(m2m=False, cascade=False, useclear=False): engine = create_engine('sqlite://', echo=True) meta = MetaData(engine)
a = Table('a', meta, Column('id', Integer, primary_key=True), Column('foo', String(30))) if m2m: b = Table('b', meta, Column('id', Integer, primary_key=True), Column('foo', String(30))) else: b = Table('b', meta, Column('id', Integer, primary_key=True), Column('foo', String(30)), Column('a_id', Integer, ForeignKey('a.id'))) if m2m: atob = Table('atob', meta, Column('a_id', Integer, ForeignKey('a.id')), Column('b_id', Integer, ForeignKey('b.id')), ) else: atob = None class A(object): def __init__(self, foo): self.foo = foo class B(object): def __init__(self, foo): self.foo = foo if cascade: use_cascade = "all, delete-orphan" else: use_cascade = "save-update" mapper(A, a, properties={ 'bs':relation(B, secondary=atob, cascade=use_cascade) }) mapper(B, b) meta.create_all() a1 = A('a1') a1.bs.append(B('b1')) a1.bs.append(B('b2')) a1.bs.append(B('b3')) sess = create_session() sess.save(a1) sess.flush() if m2m: assert atob.count().scalar() == 3 else: assert b.count(b.c.a_id == None).scalar() == 0 assert b.count().scalar() == 3 if useclear: sess.clear() a1 = sess.query(A).get(a1.id) assert len(a1.bs) == 3 a1.bs = a1.bs[1:] sess.flush() if m2m: assert atob.count().scalar() == 2 else: assert b.count(b.c.a_id != None).scalar() == 2 if cascade: assert b.count().scalar() == 2 else: assert b.count().scalar() == 3 if useclear: sess.clear() a1 = sess.query(A).get(a1.id) assert len(a1.bs) == 2 for m2m in (True, False): for cascade in (True, False): for useclear in (True, False): test(m2m, cascade, useclear)
On Oct 24, 2007, at 4:18 PM, Barry Hart wrote:
|