Попытка обернуть мою голову вокруг следующей проблемы:Остановить все на удаление каскадного SQLAlchemy
У меня есть три класса, A
, AB
и 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'
По сути, это m2m между A
и B
. Единственной нестандартной вещью является столбец id
в таблице AB
. Это по какой-то причине.
Я хочу реализовать «слияние» двух экземпляров A
. Мы даем a1
и a2
. Затем, прежде чем удалять a1
, все его отношения с AB
s должны быть переназначены до 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
s связанные с a1
благополучно переехал в a2
, однако что-то есть неправильно.
Некоторые не РЕШЕНИЕ
passive_deletes
флага. Разница в поведении касается только тех строк, которые еще не находятся в памяти, что не очень хорошо.- Добавление каскада
delete
очень рискованно для меня. Я хочу действительно убедиться, что объектыab
теряются в процессе слияния. - Обновление списков, хранящихся в ассоциациях вручную, похоже, не имеет никакого эффекта (
UPDATE
выдается снова).
Был бы очень признателен за вашу помощь!
Простое любопытство, вам удалось это решить? – Daren
Да, фактически всего несколько часов назад. Как оказалось, SQLAlchemy, похоже, не обрабатывает корректные ручные обновления объектов, присутствующих в отношениях. Либо измените свои данные, используя только API связей; или вообще не полагайтесь на отношения при выполнении обновления. – julkiewicz