2017-04-05 130 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

簡而言之,如果這是一個開發數據庫,​​刪除數據庫會更容易。如果你在生產環境中,也許你應該考慮數據遷移並切換到另一個引擎。

相關問題