下面是一些示例代码:
users_groups = Table('users_groups', Model.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('group_id', Integer, ForeignKey('groups.id'))
)
class User(Model):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
class Group(Model):
__tablename__ = 'groups'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary=users_groups, lazy='select', backref='groups')
users_dynamic = relationship('User', secondary=users_groups, lazy='dynamic')
那么这里发生的事情是,如果你像这样将一群用户添加到一个组中:
g = Group()
g.users = [User(), User(), User()]
session.add(g)
session.commit()
然后尝试删除组
session.delete(g)
session.commit()
你会得到某种形式的错误:
DELETE statement on table 'users_groups' expected to delete 3 row(s); Only 0 were matched.
删除关系的第二个版本(在我的例子中是动态关系)修复了这个问题。我什至不知道从哪里开始理解为什么会这样。在我的 SQLAlchemy 模型中的许多情况下,我一直在使用 2 个版本的各种关系,以便在给定情况下轻松使用最合适的查询策略。这是它第一次引起意外问题。
欢迎提出任何建议。
最佳答案
Group.users 和 Group.users_dynamic 关系都试图协调组被删除的事实以及能够管理它们引用的 User()
对象的事实;一个关系成功,而第二个关系失败,因为关联表中的行已被删除。最直接的解决方案是将除了一个相同的关系之外的所有关系标记为 viewonly:
class Group(Base):
__tablename__ = 'groups'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary=users_groups, lazy='select', backref='groups')
users_dynamic = relationship('User', viewonly=True, secondary=users_groups, lazy='dynamic')
如果你仍然想让两个关系都处理某种程度的突变,你需要小心地做这件事,因为 SQLAlchemy 不知道如何同时协调两个关系的变化,所以像这样的冲突如果您对两种关系进行等效突变,则可能会继续发生(如双插入等)。要单独处理“删除”问题,您还可以尝试将 Group.users_dynamic 设置为 passive_deletes=True:
class Group(Base):
__tablename__ = 'groups'
id = Column(Integer, primary_key=True)
users = relationship('User', secondary=users_groups, lazy='select', backref='groups')
users_dynamic = relationship('User', passive_deletes=True, secondary=users_groups, lazy='dynamic')
关于python - SQLAlchemy DELETE 由具有相同关系的延迟加载和动态版本引起的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17198595/