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

时间:2010-07-12 21:24:53

标签: 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) 

这是我得到的错误:

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". 

有人知道我做错了什么吗?

我还问了问题on the sqlalchemy mailing list,得到了正确答案:

  

您告诉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 个答案:

答案 0 :(得分:5)

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