Поведение при удалении с отношениями

Это не совсем проблема, я просто хочу понять. Учитывая следующий код:

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()

Я хочу, чтобы записи из таблицы ABудалялись при удалении связанных записей из B. Я попробовал 3 типа отношений (проверить в таблице B):

  • 1 :Не работает (AssertionError :Правило зависимостей пыталось очистить -столбец первичного ключа 'ab.id _b' в экземпляре '' ), тогда как при попытке удалить его непосредственно в БД корректно используются ограничения, удаляются записи из АБ.

  • 2 :Работает, я не понимаю, зачем это нужно, потому что сгенерированные базы данных идентичны (вы можете проверить разницу на выходе)

  • 3 :работает, ограничения БД делают свою работу.

Оставив (3 )отдельно, я не понимаю, зачем нужны (2 ), ведь ondelete='cascade'уже задано, и сгенерированная БД идентична. Я предполагаю, что с (1 )SQLAlchemy имеет достаточно информации для правильного поведения.

Я что-то упускаю? Спасибо.

7
задан Justin Johnson 11 October 2015 в 21:36
поделиться