Python 是什么原因造成的;依赖项规则试图将主键列“删除”;

Python 是什么原因造成的;依赖项规则试图将主键列“删除”;,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,当我试图删除由“id”标识的类别实例及其类别\u图像和文件实例时,如下所示: c = Category.query.get(id) for ci in c.images: db.session.delete(ci) db.session.flush() for ci in c.images: db.session.delete(ci.file) db.session.flush() # if i type here db.session.commit() all is fine

当我试图删除由“id”标识的类别实例及其类别\u图像和文件实例时,如下所示:

c = Category.query.get(id)
for ci in c.images:
    db.session.delete(ci)
db.session.flush()
for ci in c.images:
    db.session.delete(ci.file)
db.session.flush()  # if i type here db.session.commit() all is fine
db.session.delete(c)
db.session.commit()
class File(db.Model):                              
    __tablename__ = 'file'                                    

    id_file = Column(Integer, Sequence('seq_id_file'), primary_key=True, nullable=False)                                
    name = Column(Text, nullable=False)                       
    path = Column(Text, nullable=False, unique=True)                       
    protected = Column(Boolean, nullable=False, default=False)


class Category(db.Model):                                                           
    __tablename__ = 'category'                                                                 

    id_category = Column(Integer, Sequence('seq_id_category'), primary_key=True, nullable=False)                                                         
    name = Column(UnicodeText, nullable=False, unique=True)                                         
    images = relationship('CategoryImage', backref='images')                                   


class CategoryImage(db.Model):                                                      
    __tablename__ = 'category_image'                                                           
    __table_args__ = (                                                                         
    PrimaryKeyConstraint('id_category', 'id_file', name='seq_id_category_image'),          
    )                                                                                          

    id_category = Column(Integer, ForeignKey(Category.id_category), nullable=False)             
    id_file = Column(Integer, ForeignKey(File.id_file), nullable=False)                                      
    id_size_type = Column(Integer, nullable=)                                                  
    file = relationship(File)      
我得到一个断言错误:依赖项规则试图在实例“”上清空主键列“category\u image.id\u category”。但是,当我用commit替换flush时,它就可以工作了,flush是在删除category_image.files之后。在我将CategoryImageTable更改为Intermediate之后,我注意到了这一点。在更改之前,它有自己的pk,但没有组合,所有pk都正常工作。以下是我当前的模型定义

class File(db.Model):                              
    __tablename__ = 'file'                                    

    id_file = Column(Integer, Sequence('seq_id_file'), primary_key=True, nullable=False)                                
    name = Column(Text, nullable=False)                       
    path = Column(Text, nullable=False, unique=True)                       
    protected = Column(Boolean, nullable=False, default=False)


class Category(db.Model):                                                           
    __tablename__ = 'category'                                                                 

    id_category = Column(Integer, Sequence('seq_id_category'), primary_key=True, nullable=False)                                                         
    name = Column(UnicodeText, nullable=False, unique=True)                                         
    images = relationship('CategoryImage', backref='images')                                   


class CategoryImage(db.Model):                                                      
    __tablename__ = 'category_image'                                                           
    __table_args__ = (                                                                         
    PrimaryKeyConstraint('id_category', 'id_file', name='seq_id_category_image'),          
    )                                                                                          

    id_category = Column(Integer, ForeignKey(Category.id_category), nullable=False)             
    id_file = Column(Integer, ForeignKey(File.id_file), nullable=False)                                      
    id_size_type = Column(Integer, nullable=)                                                  
    file = relationship(File)      

现在我想弄清楚刚才发生了什么。如果我用错了,请纠正我。

下面是发生的情况。一旦对某个对象调用session.delete(),就好像已将该对象标记为删除,但尚未从db中删除。当您在删除后调用flush()时(注意:db仍然拥有该对象,因为它尚未提交),但会话已将该对象标记为已删除。因此对象变得不一致。为了使删除顺利进行,您可以始终将删除操作包装在事务中,一旦从会话中删除,您需要调用db.commit()一次,以使db会话与db一致。
class File(db.Model):                              
    __tablename__ = 'file'                                    

    id_file = Column(Integer, Sequence('seq_id_file'), primary_key=True, nullable=False)                                
    name = Column(Text, nullable=False)                       
    path = Column(Text, nullable=False, unique=True)                       
    protected = Column(Boolean, nullable=False, default=False)


class Category(db.Model):                                                           
    __tablename__ = 'category'                                                                 

    id_category = Column(Integer, Sequence('seq_id_category'), primary_key=True, nullable=False)                                                         
    name = Column(UnicodeText, nullable=False, unique=True)                                         
    images = relationship('CategoryImage', backref='images')                                   


class CategoryImage(db.Model):                                                      
    __tablename__ = 'category_image'                                                           
    __table_args__ = (                                                                         
    PrimaryKeyConstraint('id_category', 'id_file', name='seq_id_category_image'),          
    )                                                                                          

    id_category = Column(Integer, ForeignKey(Category.id_category), nullable=False)             
    id_file = Column(Integer, ForeignKey(File.id_file), nullable=False)                                      
    id_size_type = Column(Integer, nullable=)                                                  
    file = relationship(File)      

希望有帮助。

我刚刚注意到,我必须删除与中间模型相关的对象,其顺序与在表参数中声明的顺序相同,,PrimaryKeyConstraint('id\u category','id\u file')。所以当我以这种方式执行时:session.delete(category_image)、session.delete(category)、session.delete(file)和commit,或者在commit之前到处刷新,所有这些都可以正常工作。如果有人在alch文档中发现了一些关于它的信息,请告诉我。

您看过和吗?这是一种关系级联,它试图在父项删除时使外键为空。虽然您已经在会话中删除了它们,但它们仍然存在(在会话之间提交时则不是这样)。
class File(db.Model):                              
    __tablename__ = 'file'                                    

    id_file = Column(Integer, Sequence('seq_id_file'), primary_key=True, nullable=False)                                
    name = Column(Text, nullable=False)                       
    path = Column(Text, nullable=False, unique=True)                       
    protected = Column(Boolean, nullable=False, default=False)


class Category(db.Model):                                                           
    __tablename__ = 'category'                                                                 

    id_category = Column(Integer, Sequence('seq_id_category'), primary_key=True, nullable=False)                                                         
    name = Column(UnicodeText, nullable=False, unique=True)                                         
    images = relationship('CategoryImage', backref='images')                                   


class CategoryImage(db.Model):                                                      
    __tablename__ = 'category_image'                                                           
    __table_args__ = (                                                                         
    PrimaryKeyConstraint('id_category', 'id_file', name='seq_id_category_image'),          
    )                                                                                          

    id_category = Column(Integer, ForeignKey(Category.id_category), nullable=False)             
    id_file = Column(Integer, ForeignKey(File.id_file), nullable=False)                                      
    id_size_type = Column(Integer, nullable=)                                                  
    file = relationship(File)