我遇到这样的错误:
"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_id
和user_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发出了一条delete语句,但是由于错误而回滚。
我已经尝试在插入语句之后立即尝试
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
我以为double delete语句是可疑的,也许指向错误配置的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一侧没有一个约束(没有主键,没有Fereign键-它只是一个普通的原始表),但是-那就是sqlalchemy的方式,不是我的商业。
然后,当我尝试删除涉及这两行的固定对象时,sqlalchemy看到违反了它的约束,并抛出了“StaleDataError”。最后,我只需要从SQLite表中手动删除一个重复行。
关于python - 有关删除通过ORM插入的项目的SQLAlchemy StaleDataError sqlalchemy.orm.exc.StaleDataError,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8024602/