2 つのデータベース テーブルが相互に参照する外部キーを持っている状況があります。これは、SQLAlchemy 経由で MySQL を介して行われます。親を削除すると、すべての子行が削除されるようにしたい。私のスキーマ(簡略化)は次のようになります。
Parent(id, child_id, another_child_id)
Child(id, parent_id)
ondelete='CASCADE'
Child モデル定義で Parent リレーションシップを設定しました。
SQLAlchemy docs のこのセクションによると、必要なのは設定だけpost-update
であり、これにより、キー制約エラーが発生することなく、子の削除が処理されると思われます。
残念ながら、親に子を指す2つの列があるという点で、私の状況は奇妙だと思います。これは、ドキュメントの例とは異なります。親の次の関係構成では、親を削除しようとすると外部キー制約エラーが発生します (parent_id
存在する親に依存するため)。
child = relationship('Child',
primaryjoin='Child.id==Article.child_id',
post_update=True)
another_child = relationship('Child',
primaryjoin='Child.id==Article.another_child_id',
post_update=True)
私がそれを機能させる唯一の方法cascade='delete'
は、列のいずれかにフラグを立てることでした:
child = relationship('Child',
primaryjoin='Child.id==Article.child_id',
post_update=True,
cascade='delete')
another_child = relationship('Child',
primaryjoin='Child.id==Article.another_child_id',
post_update=True)
奇妙なことにcascade='delete'
、両方のカラムを装着すると、あらゆる種類の問題が発生します。例えば:
c = Child()
p = Parent()
p.child = c
p.another_child = c
session.add(p)
session.commit()
上記のコードはデータベースに親を作成しますが、列child_id
とanother_child_id
列は NULL です。子行は作成されません。
子の外部キーを保持するcascade='delete'
だけでなく、削除を子にカスケードするという私の問題を解決できる理由を誰かが説明できますか? ondelete='CASCADE'
また、両方ではなく一方の関係に設定されている場合にのみ機能するのはなぜですか (これは私にとってより論理的に思えます)。