[解決済み] SQLAlchemy: カスケード削除
2022-04-28 06:50:04
質問
SQLAlchemy のカスケードオプションについて、何か些細なことを見逃しているような気がします。
null
外部キー
ここに簡潔なテストケースを載せておきます。
from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Parent(Base):
__tablename__ = "parent"
id = Column(Integer, primary_key = True)
class Child(Base):
__tablename__ = "child"
id = Column(Integer, primary_key = True)
parentid = Column(Integer, ForeignKey(Parent.id))
parent = relationship(Parent, cascade = "all,delete", backref = "children")
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
parent = Parent()
parent.children.append(Child())
parent.children.append(Child())
parent.children.append(Child())
session.add(parent)
session.commit()
print "Before delete, children = {0}".format(session.query(Child).count())
print "Before delete, parent = {0}".format(session.query(Parent).count())
session.delete(parent)
session.commit()
print "After delete, children = {0}".format(session.query(Child).count())
print "After delete parent = {0}".format(session.query(Parent).count())
session.close()
出力します。
Before delete, children = 3
Before delete, parent = 1
After delete, children = 3
After delete parent = 0
親と子の間には、単純な一対多の関係があります。スクリプトは親を作成し、子を3つ追加し、コミットします。次に、親を削除しますが、子は残ります。子プロセスをカスケード削除するにはどうすればよいでしょうか?
どのように解決するのですか?
問題は、sqlalchemyが
Child
は親として定義されているからです (もちろん、あなたが "Child" と呼んだことは気にしません)。
もし、リレーションシップを
Parent
クラスの代わりに、それが動作します。
children = relationship("Child", cascade="all,delete", backref="parent")
(注
"Child"
を文字列で指定します。これは、宣言的なスタイルを使用する際に、まだ定義されていないクラスを参照できるようにするためです)
を追加することができます。
delete-orphan
と同様に (
delete
は、親が削除されたときに子も削除されるようにします。
delete-orphan
は、親が削除されなくても、親から "remove"された子も削除します)。
EDIT: 今知ったのですが、もし
本当に
の関係を定義したい。
Child
クラスを定義することは可能ですが、カスケードの
バックリファレンス
(のように、(明示的にバックリファレンスを作成することで、)このようになります。
parent = relationship(Parent, backref=backref("children", cascade="all,delete"))
(を意味する
from sqlalchemy.orm import backref
)
関連
-
pythonを使ったオフィス自動化コード例
-
Pythonによるjieba分割ライブラリ
-
[解決済み】「SyntaxError.Syntax」は何ですか?Missing parentheses in call to 'print'」はPythonでどういう意味ですか?
-
[解決済み】Pythonでgoogle APIのJSONコードを読み込むとエラーになる件
-
[解決済み】ValueError: xとyは同じサイズでなければならない
-
[解決済み] Pythonでファイルやフォルダを削除する方法は?
-
[解決済み] 辞書から要素を削除する
-
[解決済み] Pandas DataFrameからカラムを削除する
-
[解決済み] SQLAlchemy ORDER BY DESCENDING?
-
[解決済み] SQLAlchemy: flush() と commit() の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Python カメの描画コマンドとその例
-
PyQt5はユーザーログインGUIインターフェースとログイン後のジャンプを実装しています。
-
Evidentlyを用いたPythonデータマイニングによる機械学習モデルダッシュボードの作成
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み】csv.Error:イテレータはバイトではなく文字列を返すべき
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み】「SyntaxError.Syntax」は何ですか?Missing parentheses in call to 'print'」はPythonでどういう意味ですか?
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み】syntaxError: 'continue' がループ内で適切に使用されていない
-
[解決済み】Python Error: "ValueError: need more than 1 value to unpack" (バリューエラー:解凍に1つ以上の値が必要です