2017-08-29 4 views
1

フラスコとflask-sqlalchemyを使用してMySQLデータベースから多対多レコードを削除しようとしています。 sqlalchemyは、aのidがbにリンクされているものと同じである関係テーブルからすべての行を削除しようとしているようです。多対多の削除:Flask-Sqlalchemyは特定のIDを持つすべての行を削除しようとします

エラー(例):

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

又は

sqlalchemy.orm.exc.StaleDataError: DELETE statement on table 'ksiazka_wydawnictwo' expected to delete 552 row(s); Only 551 were matched. 

INFO sqlalchemy.engine.base.Engine DELETE FROM ksiazka_kategoria WHERE ksiazka_kategoria.ksiazka_id = %s AND ksiazka_kategoria.kategoria_id = %s 
2017-08-29 15:44:34,965 INFO sqlalchemy.engine.base.Engine ((166, 40), (167, 40), (168, 40), (169, 40), (170, 40), (171, 40), (172, 40), (173, 40) ... displaying 10 of 178 total bound parameter sets ... (1463, 19), (2046, 19)) 

関係テーブル:

ksiazka_autor = db.Table('ksiazka_autor', 
     db.Column('autor_id', db.Integer, db.ForeignKey('autor.id')), 
     db.Column('ksiazka_id', db.Integer, db.ForeignKey('ksiazka.id')) 
    ) 
     ksiazka_wydawnictwo = db.Table('ksiazka_wydawnictwo', 
     db.Column('wydawnictwo_id', db.Integer, db.ForeignKey('wydawnictwo.id')), 
     db.Column('ksiazka_id', db.Integer, db.ForeignKey('ksiazka.id')) 
    ) 
    ksiazka_ilustrator = db.Table('ksiazka_ilustrator', 
     db.Column('ilustrator_id', db.Integer, db.ForeignKey('ilustrator.id')), 
     db.Column('ksiazka_id', db.Integer, db.ForeignKey('ksiazka.id')) 
    ) 
    ksiazka_kategoria = db.Table('ksiazka_kategoria', 
     db.Column('ksiazka_id', db.Integer, db.ForeignKey('ksiazka.id')), 
     db.Column('kategoria_id', db.Integer, db.ForeignKey('kategoria.id')) 
    ) 

とモデル:

class Book(db.Model): 
    __tablename__ = 'ksiazka' 
    id = db.Column('id', db.Integer, primary_key=True) 
    [...] 

    authors = db.relationship('Author', secondary=ksiazka_autor, backref='authors', cascade="all", lazy='dynamic') 
    category = db.relationship('Category', secondary=ksiazka_kategoria, backref='category', cascade="all", lazy='dynamic') 
    publisher = db.relationship('Publisher', secondary=ksiazka_wydawnictwo, backref='publisher', cascade="all", lazy='dynamic') 
    artist = db.relationship('Artist', secondary=ksiazka_ilustrator, backref='artist', cascade="all", lazy='dynamic') 

class Author(db.Model): 
    __tablename__ = 'autor' 
    id = db.Column('id', db.Integer, primary_key=True) 
    [...] 
    books = db.relationship('Book', secondary=ksiazka_autor, backref=db.backref('books'), lazy='joined') 

class Category(db.Model): 
    __tablename__ = 'kategoria' 
    id = db.Column('id', db.Integer, primary_key=True) 
    [...] 
    cat_books = db.relationship('Book', secondary=ksiazka_kategoria, backref=db.backref('cat_books'), lazy='joined') 

class Publisher(db.Model): 
    __tablename__ = 'wydawnictwo' 
    id = db.Column('id', db.Integer, primary_key=True) 
    [...] 
    pub_books = db.relationship('Book', secondary=ksiazka_wydawnictwo, backref=db.backref('pub_books'), lazy='joined') 

class Artist(db.Model): 
    __tablename__ = 'ilustrator' 
    id = db.Column('id', db.Integer, primary_key=True) 
    [...] 
    art_books = db.relationship('Book', secondary=ksiazka_ilustrator, backref=db.backref('art_books'), lazy='joined') 

、最後にフラスココード:

@app.route('/delete/book/<id>') 
def delete_book(id): 
    book = Book.query.filter_by(id=id).first() 
    db.session.delete(book) 
    db.session.commit() 
    return redirect('/home') 
+0

これはあなたがそこにある ''カスケードオプション ''に起因すると思います。文書を参照し、削除操作で異なる動作を選択してください。 http://docs.sqlalchemy.org/en/latest/orm/cascades.html – Gigapalmer

+0

最初は、 "cascade =" all ""要素がなく、同じエラーが発生していました。 –

答えて

1

あなたが望んでいた各関係のための2つの別々の関係を設定しているためです。 Book.authorsと呼ばれる関係と、Author.authorsと呼ばれる関係と、Author.booksと呼ばれる関係と、Book.booksと呼ばれる関係があります。両方ともksiazka_autorで動作しているため、表示されている競合が発生するため、これは機能しません。あなたの他のすべての関係にも同じことが起こります。関連のインスタンスを削除し、二回のコミットが正しい解決策ではありません手動

class Book(db.Model): 
    ... 

    authors = db.relationship('Author', secondary=ksiazka_autor, back_populates='books', cascade="all", lazy='dynamic') 

class Author(db.Model): 
    ... 
    books = db.relationship('Book', secondary=ksiazka_autor, back_populates='authors', lazy='joined') 

:あなたの代わりに欲しい

back_populatesオプションを使用することです。

+0

洞察に感謝します!私は明日それを試してみましょう。私はまだSQLAlchemyを初めて使っています。 –

関連する問題