次の問題に頭を悩ませようとしています:
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が再度発行されます)。
助けていただければ幸いです。