web-dev-qa-db-ja.com

SQLAlchemyの削除がカスケードされない

私のUserモデルはAddressモデルと関係があります。リレーションシップが削除操作をカスケードするように指定しました。しかし、ユーザーをクエリして削除すると、アドレス行がまだ参照されているというエラーが発生します。ユーザーとアドレスを削除するにはどうすればよいですか?

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    addresses = db.relationship('Address', cascade='all,delete', backref='user')

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey(User.id))
db.session.query(User).filter(User.my_id==1).delete()
IntegrityError: (IntegrityError) update or delete on table "user" violates foreign key constraint "addresses_user_id_fkey" on table "address"
DETAIL:  Key (my_id)=(1) is still referenced from table "address".
 'DELETE FROM "user" WHERE "user".id = %(id_1)s' {'id_1': 1}
28
AndroidDev

次のものがあります...

_db.session.query(User).filter(User.my_id==1).delete()
_

「filter」の後でも、Queryオブジェクトが返されることに注意してください。したがって、delete()を呼び出すと、(Userオブジェクトではなく)Queryオブジェクトでdelete()を呼び出します。これは、一括削除を実行していることを意味します(おそらく単一行のみが削除されます)

あなたが使用している Query.delete() メソッドのドキュメントは...

このメソッドは、関係のPython内カスケードを提供していません-ON DELETE CASCADE/SET NULL /などが想定されています。外部キー参照を必要とするすべての外部キー参照に対して構成されています。それ以外の場合、外部キー参照が適用されている場合、データベースは整合性違反を生成する可能性があります。

言うように、この方法で削除を実行すると、設定したPythonカスケードルールが無視されます。

_user = db.session.query(User).filter(User.my_id==1).first()
db.session.delete(user)
_

それ以外の場合は、 データベースにもカスケードを設定する を確認することをお勧めします。

45
Mark Hildreth