Michael Bayer ha scritto:
the original mapping essentially expressed this relationship:
A <-- cascade="all, delete-orphan" --> B
in both directions. What that means is, there cannot be an A with no B
in the database, and there cannot be a B with no A in the database,
i.e. its either A<->B or both will be deleted. its like an oxygen
molecule, or something.
what you need to do is decide which of A and B can exist on its own
without a parent relationship. since you want to delete rows from B
and not A, that would indicate that the mapping should be:
mapper(A, a)
mapper(
B, b,
properties={
'a': relation(
A, backref=backref('b', lazy=False, uselist=False,
cascade='all, delete-orphan'),
uselist=False
)
}
)
i.e. the "delete-orphan" cascade is only in the direction from A->B.
the cascade from B->A is left at its default value of "save-update", so
delete operations dont propigate from B's to A's.
Sorry, I still have problems.
Here is the code I'm using:
from sqlalchemy import *
db = create_engine('postgres://manlio:[EMAIL PROTECTED]/test', echo=True)
metadata = BoundMetaData(db)
a = Table(
'a', metadata,
Column('x', String),
Column('y', String),
PrimaryKeyConstraint('x', 'y')
)
b = Table(
'b', metadata,
Column('x', String),
Column('y', String),
Column('z', String),
PrimaryKeyConstraint('x', 'y'),
ForeignKeyConstraint(['x', 'y'], ['a.x', 'a.y'], ondelete='CASCADE')
)
metadata.create_all()
class A(object):
def __init__(self, x, y):
self.x = x
self.y = y
class B(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
mapper(A, a)
mapper(
B, b,
properties={
'a': relation(
A, backref=backref('b', lazy=False, uselist=False,
cascade='all, delete-orphan'),
uselist=False
)
}
)
try:
#### 1
conn = db.connect()
trans = conn.begin()
sess = create_session(bind_to=conn)
o = A('1', '2')
o.b = B(o.x, o.y, '3')
sess.save(o)
sess.flush()
sess.close()
trans.commit()
conn.close()
#### 2
conn = db.connect()
trans = conn.begin()
sess = create_session(bind_to=conn)
sess.update(o)
print o.b.z
del o.b
#sess.delete(o.b)
#o.b = None
sess.flush()
sess.close()
trans.commit()
conn.close()
#### 3
print o.b
s = a.select()
print conn.execute(s).fetchall()
finally:
metadata.drop_all(tables=[b])
metadata.drop_all(tables=[a])
The error is:
Traceback (most recent call last):
File "alchemy.py", line 82, in ?
print o.b
File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py",
line 48, in __get__
return self.get(obj)
File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py",
line 205, in get
value = callable_()
File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/strategies.py",
line 204, in lazyload
raise exceptions.InvalidRequestError("Parent instance %s is not
bound to a Session, and no contextual session is established; lazy load
operation of attribute '%s' cannot proceed" % (instance.__class__,
self.key))
sqlalchemy.exceptions.InvalidRequestError: Parent instance <class
'__main__.A'> is not bound to a Session, and no contextual session is
established; lazy load operation of attribute 'b' cannot proceed
Thanks and regards Manlio Perillo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---