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

cdu*_*ruk 14 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.
Run Code Online (Sandbox Code Playgroud)

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

我有一个page_view模型,它有一个外键page_id和a 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'
)
Run Code Online (Sandbox Code Playgroud)

这是关系的样子

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

我使用insert语句将一些项添加到我的数据库,类似于:

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)
Run Code Online (Sandbox Code Playgroud)

据我所知,从日志中可以正确地提交事务,我在数据库中看到了这些项目.

但是,当我尝试使用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
Run Code Online (Sandbox Code Playgroud)

我认为双删除声明是一个嫌疑人,可能指向错误配置的ORM关系,但我不认为是这种情况.

yen*_*sun 7

我想我可以暗示这个问题.简短版本是:"您可能必须手动修改数据库中的数据才能解决问题".

版本较长:我和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')))
Run Code Online (Sandbox Code Playgroud)

看到那个复合主键?我以某种方式设法插入两行具有相同的recipe_title/product_title对.我惊讶地发现SQLite对于这个表没有一个约束(没有主键,没有fereign键 - 它只是一个简单的香草表),但很好 - 就像sqlalchemy去的那样,而不是我的商业.

然后当我尝试删除涉及这两行的持久对象时,sqlalchemy看到它的约束被违反并且它抛出了'StaleDataError'.最后,我只需要从SQLite表中手动删除一个duplicatinng行.