Dies ist nicht wirklich ein Problem, ich will nur verstehen. Betrachtet man den folgenden Code:Löschverhalten mit Beziehung
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()
class AB(Base):
__tablename__= 'ab'
id_a = Column(Integer, ForeignKey('a.id', ondelete='CASCADE'), primary_key=True)
id_b = Column(Integer, ForeignKey('b.id', ondelete='CASCADE'), primary_key=True)
rel = Column(Unicode)
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
#1: doesn’t work try to set id_b to null
rel_a = relationship('AB')
# Works, but cascade='all' seems uneeded to me
rel_a = relationship('AB', cascade='all')
# Works
rel_a = relationship('AB', passive_deletes=True)
engine = create_engine('sqlite://', echo=True)
import logging
logger = logging.getLogger('sqlalchemy.engine.base.Engine')
logger.setLevel(logging.DEBUG)
handler = logger.handlers[0]
handler.setLevel(logging.DEBUG)
handler.setFormatter(logging.Formatter('%(levelname)s %(message)s', ''))
Base.metadata.create_all(engine)
sess = sessionmaker(engine)()
a1 = A()
b1 = B()
ab = AB()
sess.add_all([a1,b1])
sess.flush()
ab.id_a = a1.id
ab.id_b = b1.id
ab.rel = u'truite'
sess.add(ab)
sess.flush()
sess.delete(b1)
sess.flush()
Ich möchte Datensätze aus AB
Tabelle entfernt werden, wenn verknüpfte Datensätze aus B
entfernt werden. Ich habe versucht, drei Arten von Beziehungen (Check-in B Tabelle):
1: Funktioniert nicht (AssertionError: Abhängigkeit der Regel versucht, Ausblendung Primärschlüsselspalte 'ab.id_b' auf Instanz '') Wenn dagegen versucht wird, es direkt in der Datenbank zu entfernen, werden Einschränkungen korrekt verwendet, und Datensätze von AB werden entfernt.
2: Works, ich verstehe nicht, warum dies erforderlich ist, weil erzeugten Datenbanken identisch sind (Sie die diff auf Ausgang überprüfen)
3: Arbeiten, tun die DB Zwänge die Arbeit.
Weggehen (3) auseinander, erhalte ich nicht, warum (2) erforderlich ist, weil die ondelete='cascade'
bereits gesetzt ist, und erzeugt DB identisch ist. Meine Vermutung wäre mit (1), SQLAlchemy hat genug Informationen, um das richtige Verhalten zu haben.
Fehle ich etwas? Vielen Dank.
Vielen Dank für diese Frage. Wirklich hilfreich. – clime