Python SQLAlchemy不级联删除多个级别
我对炼金术有点陌生。我到处寻找我的问题的答案,但我没有找到适合我的情况的答案 简而言之,只要TestResults中没有相关记录,删除发布模型中的记录将删除其他模型中的所有记录。但是,如果TestResult中有相关记录,那么删除发布将不起作用。似乎删除父母会删除孩子和孩子的孩子,但不会删除孩子的孩子。以下是一些代码,有助于强调这一点:Python SQLAlchemy不级联删除多个级别,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我对炼金术有点陌生。我到处寻找我的问题的答案,但我没有找到适合我的情况的答案 简而言之,只要TestResults中没有相关记录,删除发布模型中的记录将删除其他模型中的所有记录。但是,如果TestResult中有相关记录,那么删除发布将不起作用。似乎删除父母会删除孩子和孩子的孩子,但不会删除孩子的孩子。以下是一些代码,有助于强调这一点: class Release(db.Model): __tablename__ = 'releases' id = db.Column(db.In
class Release(db.Model):
__tablename__ = 'releases'
id = db.Column(db.Integer, primary_key=True)
platform_id=db.Column(db.Integer, db.ForeignKey('platforms.id'))
name = db.Column(db.String(20), unique=True)
builds = db.relationship('ReleaseBuilds', cascade='all,delete', lazy='dynamic', order_by="desc(ReleaseBuilds.date_created)")
class ReleaseBuilds(db.Model):
__tablename__='release_builds'
id = db.Column(db.Integer, primary_key=True)
release_id = db.Column(db.Integer, db.ForeignKey('releases.id'))
name = db.Column(db.String(150), nullable=False)
artifacts = db.relationship('ReleaseBuildArtifacts', cascade='all,delete', backref='builds', lazy='dynamic')
deployments = db.relationship('Deployments', cascade='all,delete', lazy='dynamic')
tests = db.relationship('Test', cascade='delete', lazy='dynamic')
class ReleaseBuildArtifacts(db.Model):
__tablename__='release_build_artifacts'
id = db.Column(db.Integer, primary_key=True)
release_build_id = db.Column(db.Integer, db.ForeignKey('release_builds.id'))
application_id = db.Column(db.Integer, db.ForeignKey('applications.id'))
rpm = db.Column(db.String(300))
build = db.relationship('ReleaseBuilds')
application = db.relationship('Application')
class Deployments(db.Model):
__tablename__ = 'deployments'
release_build_id = db.Column(db.Integer, db.ForeignKey('release_builds.id'), primary_key=True)
environment_id = db.Column(db.Integer, db.ForeignKey('environments.id'), primary_key=True)
date_deployed = db.Column(db.DateTime(timezone=False), default=datetime.datetime.utcnow)
environment = db.relationship('Environment', foreign_keys=[environment_id])
class TestType(db.Model):
__tablename__ = 'test_types'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True)
class Test(db.Model):
__tablename__ = 'tests'
id = db.Column(db.Integer, primary_key=True)
release_build_id = db.Column(db.Integer, db.ForeignKey('release_builds.id'), nullable=False)
environment_id = db.Column(db.Integer, db.ForeignKey('environments.id'), nullable=False)
test_type_id = db.Column(db.Integer, db.ForeignKey('test_types.id'))
name = db.Column(db.String(300))
environments = db.relationship('Environment', foreign_keys=[environment_id])
results = db.relationship('TestResult', cascade='all,delete', lazy='dynamic')
__table_args__ = (
ForeignKeyConstraint(['release_build_id', 'environment_id'],['deployments.release_build_id', 'deployments.environment_id']),
)
class TestResult(db.Model):
__tablename__ = 'test_results'
id = db.Column(db.Integer, primary_key=True)
test_id = db.Column(db.Integer, db.ForeignKey('tests.id'), nullable=False)
name = db.Column(db.String(500))
passed = db.Column(db.Boolean)
关于此级联删除不起作用的原因有何建议 我在我们的项目中遇到了一个类似的问题,我们在ORM级别定义了级联,还使用了
lazy=dynamic
关系。这导致级联不能在最底层的子级上运行
动态加载导致关系在访问时返回查询
对象
为了提高性能,查询上的删除非常有限,如下所述:
该方法在Python中不提供关系的级联—它是
假设为任何类型配置了ON DELETE CASCADE/SET NULL/etc
需要它的外键引用,否则数据库可能会
如果正在执行外键引用,则发出完整性冲突
强制执行
删除后,会话中受影响的从属对象
按ON DELETE可能不包含当前状态,或者可能已被删除
删除。一旦会话过期,此问题即会得到解决
通常在Session.commit()时发生,也可以使用
Session.expire_all()。访问行已被删除的过期对象
删除
将调用SELECT来定位行;当找不到该行时,
将引发ObjectDeletedError
因此,问题的解决方案可以是在数据库级别定义级联,也可以使用其他类型的关系
这里提出了相关问题:
编辑:(我应用的解决方案正在更改查询级别的加载类型-输入选项)