python - SQLAlchemy StaleDataError 删除通过 ORM sqlalchemy.orm.exc.StaleDataError 插入的项目

标签 python mysql database sqlalchemy pyramid

我遇到了一个问题,出现了如下错误:

"MyPyramidApplication Error"<class 'sqlalchemy.orm.exc.StaleDataError'>: DELETE statement on table 'page_view' expected to delete 6 row(s); Only 0 were matched.

所以,我很清楚是什么导致了这个问题,但我一直无法解决它。

我有一个 page_view 模型,它在 page_iduser_id 上有一个外键。

这是模型的样子:

page_view_table = sa.Table(
   'page_view',
    metadata,
    sa.Column('id', sa.Integer, primary_key=True),
    sa.Column('page_id', sa.Integer, sa.ForeignKey('guide.id')),
    sa.Column('user_id', sa.Integer, sa.ForeignKey('user.id')),
    sa.Column('last_view', sa.DateTime, nullable=False),
    sa.UniqueConstraint('user_id', 'page_id'),
    mysql_engine='InnoDB',
    mysql_charset='utf8mb4'
)

关系是这样的

orm.mapper(Page, page_table,
    properties = {
        'users_viewed': sa.orm.relation(
            User,
            secondary=page_view_table,
            backref='page'),
    }
)

我正在使用插入语句将一些项目添加到我的数据库中,类似于此:

ins = model.page_view_table.insert()
sql = str(ins)
sql += ' ON DUPLICATE KEY UPDATE last_view = :last_view'
session = model.Session()
session.execute(sql, page_views)
mark_changed(session)

据我从日志中得知,事务已正确提交并且我在数据库中看到了项目。

但是,当我尝试使用 ORM 删除页面项目时,出现 StaleDataError 异常。查看日志,我看到 ORM 发出删除语句但随后由于错误回滚。

我已经尝试在插入语句之后立即使用 session.expire_all()session.expunge_all() 进行试验,但它们不是很有用,我仍然错误。

这是我在 SQLAlchemy 日志中看到的内容。

2011-11-05 18:06:08,031 INFO  [sqlalchemy.engine.base.Engine][worker 3] DELETE FROM page_view WHERE page_view.page_id = %s AND page_view.user_id = %s
2011-11-05 18:06:08,031 INFO  [sqlalchemy.engine.base.Engine][worker 3] (13818L, 259L)
2011-11-05 18:06:08,032 INFO  [sqlalchemy.engine.base.Engine][worker 3] DELETE FROM page_view WHERE page_view.page_id = %s AND page_view.user_id = %s
2011-11-05 18:06:08,033 INFO  [sqlalchemy.engine.base.Engine][worker 3] (13818L, 259L)
2011-11-05 18:06:08,033 INFO  [sqlalchemy.engine.base.Engine][worker 3] ROLLBACK

我认为双重删除语句是可疑的,可能指向错误配置的 ORM 关系,但我认为情况并非如此。

最佳答案

我想我可以就这个问题给出一个提示。简短的版本是:“您可能必须手动修改数据库中的数据才能解决问题”。

较长的版本:我在使用 SQLite 时遇到了类似的问题。我映射了下表:

ingredients = Table('ingredients', metadata,
    Column('recipe_title', Unicode, ForeignKey('recipes.title'), primary_key=True),
    Column('product_title', Unicode, ForeignKey('products.title'), primary_key=True),
    Column('amount', Integer, nullable=False),
    Column('unit_title', Unicode, ForeignKey('units.title')))

看到复合主键了吗?我以某种方式设法插入了具有相同 recipe_title/product_title 对的两行。我很惊讶地发现这个表的 SQLite 方面没有单一约束(没有主键,没有 feeign 键 - 它只是一个普通的 Vanilla 表),但是 - 这就是 sqlalchemy 的方式,而不是我的业务。

然后,当我尝试删除涉及这两行的持久化对象时,sqlalchemy 发现它的约束被违反,并抛出“StaleDataError”。最后我只需要从 SQLite 表中手动删除一个重复的行。

关于python - SQLAlchemy StaleDataError 删除通过 ORM sqlalchemy.orm.exc.StaleDataError 插入的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8024602/

相关文章:

python - 将两列合并为 pandas 中的日期时间

python - 一步初始化附加到列表的defaultdict?

php - 从数组中查找与 cookie 不匹配的值

database - rethinkdb index-rebuild 提示 python 驱动程序丢失

php - 如何用 python 重写这个 POST curl 脚本?

Python: pickle 嵌套函数

mysql - SQL - 查找具有最大行数的行集的 id/"x_id"

php - 从 MySQL "most clicked items in the past 6 hours"中检索?

php - 如何在 Laravel Eloquent 中指定多个一对一关系?

sql - 检索具有属性名称的指定列记录