python - SQLAlchemy DELETE 由具有相同关系的延迟加载和动态版本引起的错误

标签 python mysql sqlalchemy

下面是一些示例代码:

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/

相关文章:

python - pandas 在 csv 上提高 OutOfBoundsDatetime 但不在 sql 上提高 OutOfBoundsDatetime

python - 根据符号将列中的值拆分为新行

python - 从字典列表创建 NumPy 记录数组的最简单方法?

MYSQL:如何在不查询整个表的情况下获取过去X小时内插入的行

php - 如何从按时间戳过滤的数据库中选择结果?

python - 使用(仅)SQLAlchemy Core 的 Flask 应用程序模式

python - 我可以用 python 生成真实的随机数吗?

python argparse 停止工作

php - 如何进行多插入和获取ID

python - select() 和 table.select() 的区别