次の問題に頭を悩ませようとしています:
A
、AB
およびの3 つのクラスがありますB
。
class AB(Base):
id = Column(Integer, primary_key=True)
a_id = Column(Integer, ForeignKey('a.id'), nullable=False)
a = relationship(
'A',
cascade='save-update',
backref=backref(
'abs',
cascade='save-update',
uselist=True
)
)
b_id = Column(Integer, ForeignKey('b.id'), nullable=False)
b = relationship(
'B',
cascade='save-update',
backref=backref(
'abs',
cascade='save-update',
uselist=True
)
)
__tablename__ = 'ab'
class A(Base)
id = Column(Integer, primary_key=True)
__tablename__ = 'a'
class B(Base)
id = Column(Integer, primary_key=True)
__tablename__ = 'b'
A
基本的に、これはとの間の m2m 関係B
です。唯一の非標準的なことはid
、テーブルに列があることですAB
。それには理由があります。
の 2 つのインスタンスの「マージ」を実装したいと考えていますA
。と が与えられa1
ますa2
。次に、 を削除する前に、 とのa1
すべての関係をAB
に再割り当てする必要がありますa2
。プロセスでの値を保持することは非常に重要ですAB.id
(したがって、 の新しいインスタンスをAB
実際に作成または削除するべきではありません)。
問題 どのようにしようとしても、 のインスタンスを削除するたびにA
、SQLAlchemy はforeign_key を値で更新しようとするため、NULL
結果としてNOT NULL
制約が破られます。それは明示的に発行することによってそれを行いUPDATE ab SET a_id = NULL WHERE id = ...
ます。プログラムに次のループがありますが、そうします。
for ab in a1.abs:
ab.a_id = a2.id
session.db.add(ab)
session.db.delete(a1)
ab
したがって、削除が発行される前に、に関連するすべての sa1
が安全に に移動されたように思えますがa2
、何かが間違っています。
いくつかの非解決策
passive_deletes
旗。動作の違いは、メモリにまだ存在しない行のみに関係するため、適切ではありません。delete
カスケードを追加することは、私にとって非常に危険です。ab
マージの過程でオブジェクトが失われないようにしたいのです。- アソシエーションに保持されているリストを手動で更新しても、何の効果もないようです (The
UPDATE
が再度発行されます)。
助けていただければ幸いです。