当我尝试通过以下方式删除由“ 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后的flush时,它可以工作。我将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)
现在,我正在尝试弄清刚刚发生的事情。如果我使用的是错误的东西,请纠正我。
答案 0 :(得分:0)
这是正在发生的事情。在某个对象上调用session.delete()之后,就好像已将该对象标记为要删除但尚未从数据库中删除。在删除后调用flush()时(注意:db仍具有该对象,因为尚未提交),但是session已将该对象标记为已删除。因此,对象变得不一致。为了使删除顺利进行,您始终可以将删除操作包装在事务中,一旦将它们从会话中删除,则需要调用db.commit()一次,以使数据库会话与数据库保持一致。 希望对您有所帮助。
答案 1 :(得分:0)
我刚刚注意到,必须删除与中间模型有关的对象beeing,对象的顺序与 table_args ,PrimaryKeyConstraint('id_category','id_file')中声明的顺序相同。因此,当我以这种方式执行它时:session.delete(category_image),session.delete(category),session.delete(file)并提交它或在提交之前刷新到所有位置,然后一切正常。如果有人在Alch文档中发现有关此问题的信息,请告诉我。