【问题标题】:What could be the cause of "Dependency rule tried to blank-out primary key column"“依赖规则试图清除主键列”的原因可能是什么
【发布时间】:2018-08-13 15:33:17
【问题描述】:

当我尝试删除由 'id' 标识的类别实例及其 category_image 和文件实例时,如下所示:

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

我收到一个 AssertionError:依赖规则试图清除实例“”上的主键列“category_image.id_category”。但是,当我用提交替换删除 category_image.files 之后的刷新时,它就可以工作了。在我将 CategoryImage 表更改为中介后,我注意到了这一点。在更改之前,它有自己的 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)      

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

【问题讨论】:

标签: python sqlalchemy flask-sqlalchemy


【解决方案1】:

这就是正在发生的事情。一旦您在某个对象上调用 session.delete() ,就好像已将对象标记为删除但尚未从数据库中删除。当您在删除后调用 flush() 时(注意:db 仍然拥有该对象,因为它尚未提交)但会话已将该对象标记为已删除。所以对象变得不一致。为了使删除顺利进行,您始终可以将删除操作包装在事务中,一旦从会话中删除它们,您需要调用一次 db.commit() 以使数据库会话与数据库一致。 希望对您有所帮助。

【讨论】:

  • > 你总是可以将你的删除操作包装在一个事务中 你如何用 SQLAlchemy 做到这一点?似乎Session 对象无论如何都会自动执行此操作,那么如何精细控制呢?
【解决方案2】:

我刚刚注意到我必须按照 table_args 中声明的顺序删除与中间模型相关的对象,PrimaryKeyConstraint('id_category', 'id_file')。因此,当我以这种方式执行它时: session.delete(category_image), session.delete(category), session.delete(file) 并在提交之前提交或刷新任何地方,然后一切正常。如果有人在 alch 文档中发现有关它的内容,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2010-12-09
    • 2013-02-16
    • 2021-09-01
    • 2012-01-01
    • 2021-04-09
    • 2017-09-09
    相关资源
    最近更新 更多