Python SQLAlchemy不级联删除多个级别

Python SQLAlchemy不级联删除多个级别,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我对炼金术有点陌生。我到处寻找我的问题的答案,但我没有找到适合我的情况的答案 简而言之,只要TestResults中没有相关记录,删除发布模型中的记录将删除其他模型中的所有记录。但是,如果TestResult中有相关记录,那么删除发布将不起作用。似乎删除父母会删除孩子和孩子的孩子,但不会删除孩子的孩子。以下是一些代码,有助于强调这一点: class Release(db.Model): __tablename__ = 'releases' id = db.Column(db.In

我对炼金术有点陌生。我到处寻找我的问题的答案,但我没有找到适合我的情况的答案

简而言之,只要TestResults中没有相关记录,删除发布模型中的记录将删除其他模型中的所有记录。但是,如果TestResult中有相关记录,那么删除发布将不起作用。似乎删除父母会删除孩子和孩子的孩子,但不会删除孩子的孩子。以下是一些代码,有助于强调这一点:

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

因此,问题的解决方案可以是在数据库级别定义级联,也可以使用其他类型的关系

这里提出了相关问题:

编辑:(我应用的解决方案正在更改查询级别的加载类型-输入选项)