Каскадное удаление в таблицу сопоставления «многие ко многим»? - PullRequest
7 голосов
/ 13 июля 2010

У меня проблема с каскадным удалением. У меня есть две таблицы, и они сопоставлены многие ко многим:

class File(object): pass 
file_table = Table('file', metadata, 
        Column('id', Integer, primary_key=True, autoincrement=True), 
        Column('filename', String(255)), 
} 

class FileHost(object): pass 
file_host = Table('host', metadata, 
        Column('id', Integer, primary_key=True, autoincrement=True ), 
        Column('name', String(255)), 
) 

file_hosted = Table('file_hosted', metadata, 
        Column('id_host', Integer, ForeignKey('host.id')), 
        Column('id_file', Integer, ForeignKey('file.id')) 
) 

session.mapper(File, file_table, properties={ 
    'host': relation(FileHost, secondary=file_hosted, backref='files', 
                        cascade='all,delete-orphan', single_parent=True) 
}) 
session.mapper(FileHost, file_host) 

Это ошибка, которую я получаю:

sqlalchemy.exc.IntegrityError: 
(IntegrityError) update or delete on table "file" violates
foreign key constraint "file_hosted_id_file_fkey" on table "file_hosted" 
DETAIL:  Key (id)=(50905) is still referenced from table "file_hosted". 

Кто-нибудь понял, что я делаю не так?

Я также задал вопрос в списке рассылки sqlalchemy и получил правильный ответ:

Вы говорите SQLAlchemy о каскадном удалении файлов в FileHost, но вы хочу это наоборот. Вы можете исправить это, переместив cascade = 'all, delete-orphan' и single_parent = True предложения в backref. Вы также, вероятно, хотите uselist = False.

session.mapper(File, file_table, properties={ 
    'host': relation(FileHost, 
                     backref=backref('files', 
                                     cascade='all,delete-orphan', 
                                     single_parent=True), 
                     secondary=file_hosted, 
                     uselist=False) 
}) 

1 Ответ

5 голосов
/ 07 августа 2013

Следует отметить, что хотя это не было проблемой в данном конкретном случае, вы все равно можете получить эту ошибку, если не включите ondelete="CASCADE" в объявление ваших внешних ключей.Даже после объявления cascade="all,delete" в моих отношениях я все еще получал эту ошибку, пока не добавил атрибут ondelete.Вы также можете добавить onupdate="CASCADE".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...