I'm using SQLAlchemy 0.7.1 on a MySQL 5.1.57 database, and I'm getting
unexpected behavior with the cascade_backrefs=False parameter for my
many-to-many relationships.
Here's the pertinent table code:
Base = declarative_base()
class ZKGroup(Base):
__tablename__ = 'groups'
id = Column(Integer, primary_key=True)
name = Column(String(512))
def __init__(self, name)
self.name = name
user_groups = Table('user_groups', Base.metadata,
Column('user_id', String(128), ForeignKey('users.username')),
Column('group_id', Integer, ForeignKey('groups.id'))
)
class ZKUser(Base):
__tablename__ = 'users'
username = Column(String(128), primary_key=True)
groups = relationship(ZKGroup, secondary=user_groups,
backref='users', cascade_backrefs=False)
def __init__(self, username, groups)
self.username = username
self.groups = groups
Now, I would expect the cascade_backrefs=False option to prevent newly
created ZKUser objects with a persistent ZKGroup object in their
'groups' list to not be added to the session. But the ZKUser object
appears to being getting added to the session anyway. I can tell
because this code:
group = ZKGroup('group1')
session.add(group)
user = ZKUser('user1')
session.add(user)
self.session.commit()
user2 = ZKUser('user1', [group])
session.merge(user2)
session.commit()
Throws this exception from the session.merge() call:
Traceback (most recent call last):
File "TestScript.py", line 7
session.merge(user2)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1220, in
merge
self._autoflush()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 901, in
_autoflush
self.flush()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1473, in
flush
self._flush(objects)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 1542, in
_flush
flush_context.execute()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/unitofwork.py", line 327,
in execute
rec.execute(self)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/unitofwork.py", line 471,
in execute
uow
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/
lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 1902, in
_save_obj
state_str(existing)))
FlushError: New instance <ZKUser at 0x10412f3d0> with identity key
(<class 'zookeeper.common.model.ZKUser.ZKUser'>, ('user1',)) conflicts
with persistent instance <ZKUser at 0x1040fce10>
However, if I add a call to 'session.expunge(user2)' right before
'session.merge(user2)', the merge completes and user1 gets associated
to group1 in the DB, as expected.
Is this a bug with cascade_backrefs=False? Or is it just not meant to
be used with many-to-many relationships, or something like that?
--
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.