Python 是什么原因造成的;依赖项规则试图将主键列“删除”;
当我试图删除由“id”标识的类别实例及其类别\u图像和文件实例时,如下所示: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
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)