2017-04-05 131 views
1

我正在使用Flask-SQLAlchemy。我有两个通过关联表共享关系的类。当我尝试删除其中一个表中的一行时。我看到以下错误:烧瓶SQLAlchemy多对多StaleDataError

sqlalchemy.orm.exc.StaleDataError 
StaleDataError: DELETE statement on table 'tags' expected to delete 1 row(s); Only 2 were matched. 

这里是我的模型:

tags = db.Table('tags', 
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')), 
    db.Column('post_id', db.Integer, db.ForeignKey('posts.id')) 
) 

class Post(db.Model): 
    __tablename__ = 'posts' 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(255)) 
    tags = db.relationship('Tag', secondary=tags, 
         backref=db.backref('posts', lazy='dynamic')) 

    def __init__(self, **kwargs): 
     super(Post, self).__init__(**kwargs) 

    def __repr__(self): 
     return '<title %r>' % self.title 


class Tag(db.Model): 
    __tablename__ = 'tag' 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(120), unique=True) 

的这里是我跑删除代码:

def remove_tag(tag_id): 
    tag = Tag.query.get(tag_id) 
    for post in tag.posts: 
     p = Post.query.get(post.id) 
     p.tags.remove(tag) 
db.session.delete(tag) 
db.session.commit() 

我已经尝试了条纹下来的版本此代码以外的应用程序,在独立测试,数据库和环境中。并且,它按预期工作,移除标签和关联的表格行。

我想知道,如果可能的话:

  • 我怎么在StaleDataError的局面得到什么?
  • 为什么它匹配多个行时,当我的查询.all()不显示多个用途?
  • 我该如何防止这种情况发生?

在此先感谢您的任何帮助。

最佳, 爱德华

+0

我在你的例子中修正了一些缩进,但留下了'remove_tag()',尽管它似乎也有一些错误。你能检查吗? –

回答

0

有所顿悟!

How did I get in the situation of a StaleDataError ?

当测试我的编辑后页面时,我做了同一帖子的很多POST到数据库。

Why does it match more than one row, when my query to .all() doesn't show multiple uses?

我的测试在关联表中创建了多个条目。换句话说,我有(tag.id= 1, post.id=1)多次。

How can I prevent this from happening?

将唯一约束添加到关联表以停止多个条目到您的数据库。我还在我看来添加了检查来停止多个条目。

tags = db.Table(
    'tags', 
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')), 
    db.Column('post_id', db.Integer, db.ForeignKey('posts.id')), 
    db.UniqueConstraint('tag_id', 'post_id', name='UC_tag_id_post_id') 
) 

迁移您的数据库。

如果您使用SQlite和Alembic,您很可能会遇到此错误:“不支持SQLite方言中的ALTER约束”。有关此问题的更多信息,请参见here

简而言之,如果这是一个开发数据库,​​删除数据库会更容易。如果你在生产环境中,也许你应该考虑数据迁移并切换到另一个引擎。

相关问题