将删除级联到多对多关联表?

tom*_*tom 8 sqlalchemy

我有一个级联删除的问题.我有两个表,它们被映射为多对多:

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) 
Run Code Online (Sandbox Code Playgroud)

这是我得到的错误:

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". 
Run Code Online (Sandbox Code Playgroud)

有谁知道我做错了什么?

我还在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) 
}) 
Run Code Online (Sandbox Code Playgroud)

Cha*_*ann 5

应该注意的是,虽然在这种特殊情况下这不是问题,但如果您没有包含ondelete="CASCADE"外键声明,则仍可能出现此错误.即使cascade="all,delete"在我的关系中声明之后,我仍然会收到此错误,直到我添加了该ondelete属性.您可能还想添加onupdate="CASCADE".

  • 为了澄清这一点...... `ondelete="CASCADE"` 指示数据库本身在外键上创建级联删除。`cascade="all,delete"` 是 sqlalchemy 管理级联的指令。请参阅此链接下方的绿色框:http://docs.sqlalchemy.org/en/latest/orm/cascades.html#delete (2认同)