简体   繁体   English

(pymysql.err.IntegrityError)(1451,'无法删除或更新父行:外键约束失败...')

[英](pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails…') in Flask

I'm aware that there are many questions about the error in the title, but I could't find a suitable solution. 我知道标题中的错误有很多问题,但是我找不到合适的解决方案。 My problem is that while deleting a row using Session.delete() it's throwing 我的问题是,使用Session.delete()删除行时,它会抛出

sqlalchemy.exc.IntegrityError: (pymysql.err.IntegrityError) (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (`transport`.`driver`, CONSTRAINT `driver_ibfk_1` FOREIGN KEY (`owner_id`) REFERENCES `truckcompany` (`id`))') [SQL: 'DELETE FROM truckcompany WHERE truckcompany.id = %(id)s'] [parameters: {'id': 4}]

Models: 楷模:

class Truck_company(Base):

    __tablename__ = 'truckcompany'

    id = Column(BigInteger, primary_key=True)

class Driver(Base):

    __tablename__ = 'driver'

    id = Column(BigInteger, primary_key=True)
    owner_id = Column(BigInteger, ForeignKey('truckcompany.id'))
    owner = relationship(Truck_company)

The view with the failing delete: 删除失败的视图:

@app.route('/values/deleteuser/<int:id>', methods=['POST', 'GET'])
def delete_truck(id):
    value_truckcompany = sqlsession.query(Truck_company).filter(Truck_company.id == id).first()
    if value_truckcompany:
        sqlsession.delete(value_truckcompany)
        sqlsession.commit()
        return redirect('/static/truckcompanyview', )

Why 为什么

In your Driver model there's a foreign key constraint referencing Truck_company : 在您的Driver模型中,有一个外键约束引用Truck_company

class Driver(Base):
    ...
    owner_id = Column(BigInteger, ForeignKey('truckcompany.id'))

You've omitted the ON DELETE action, so MySQL defaults to RESTRICT . 您已经省略了ON DELETE操作,因此MySQL 默认为RESTRICT Also there are no SQLAlchemy ORM relationships with cascades that would delete the related drivers. 此外,不存在带有级联的SQLAlchemy ORM关系,该关系会删除相关的驱动程序。 So when you try to delete the truck company in the view, the DB stops you from doing that, because you'd violate your foreign key constraint and in other words referential integrity . 因此,当您尝试在视图中删除卡车公司时,数据库会阻止您这样做,因为您违反了外键约束,即违反了参照完整性 This is an issue with how you've modeled your DB, not Flask etc. 这是如何建模数据库而不是Flask等的问题。

What can I do 我能做什么

The most important thing to do – when you're creating your model – is to decide what would you like to happen when you delete a truck company with related drivers. 创建模型时,最重要的事情是确定删除带有相关驾驶员的卡车公司时要发生的情况。 Your options include, but are not limited to: 您的选择包括但不限于:

  1. Deleting the drivers also. 也删除驱动程序。
  2. Setting their owner_id to NULL, effectively detaching them. 将其owner_id设置为NULL,可以有效地分离它们。 This is what SQLAlchemy does, if an ORM relationship is present in its default configuration in the parent. 如果在父级的默认配置中存在ORM关系,这就是SQLAlchemy所做的。

It is also a perfectly valid solution to restrict deleting parent rows with children, as you've implicitly done. 就像您已隐式完成的一样,这也是限制删除带有子项的父行的完美有效解决方案。

You've expressed in the comments that you'd like to remove the related drivers. 您已在评论中表示要删除相关的驱动程序。 A quick solution is to just manually issue a DELETE: 一种快速的解决方案是仅手动发出DELETE:

# WARNING: Allowing GET in a data modifying view is a terrible idea.
# Prepare yourself for when Googlebot, some other spider, or an overly
# eager browser nukes your DB.
@app.route('/values/deleteuser/<int:id>', methods=['POST', 'GET'])
def delete_truck(id):
    value_truckcompany = sqlsession.query(Truck_company).get(id)

    if value_truckcompany:
        sqlsession.query(Driver).\
            filter_by(owner=value_truckcompany).\
            delete(synchronize_session=False)
        sqlsession.delete(value_truckcompany)
        sqlsession.commit()
        return redirect('/static/truckcompanyview', )

This on the other hand fixes this one location only. 另一方面,这仅修复该位置。 If you decide that a Driver has no meaning without its Truck_company , you could alter the foreign key constraint to include ON DELETE CASCADE, and use passive deletes in related SQLAlchemy ORM relationships: 如果您确定一个没有它的Truck_companyDriver没有任何意义,则可以更改外键约束以包括ON DELETE CASCADE,并在相关的SQLAlchemy ORM关系中使用被动删除

class Truck_company(Base):
    ...
    # Remember to use passive deletes with ON DELETE CASCADE
    drivers = relationship('Driver', passive_deletes=True)

class Driver(Base):
    ...
    # Let the DB handle deleting related rows
    owner_id = Column(BigInteger, ForeignKey('truckcompany.id',
                                             ondelete='CASCADE'))

Alternatively you could leave it to the SQLAlchemy ORM level cascades to remove related objects, but it seems you've had some problems with that in the past. 或者,您可以将其留给SQLAlchemy ORM级别级联以删除相关的对象,但是过去您似乎在此方面遇到了一些问题。 Note that the SQLAlchemy cascades define how an operation on the parent should propagate to its children, so you define delete and optionally delete-orphan on the parent side relationship, or the one-to-many side: 请注意, SQLAlchemy级联定义了父级操作应如何传播到其子级,因此您可以在父级关系或一对多关系上定义deletedelete-orphan可选):

class Truck_company(Base):
    ...
    # If a truck company is deleted, delete the related drivers as well
    drivers = relationship('Driver', cascade='save-update, merge, delete')

In your current model you have no relationship defined from Truck_company to Driver , so no cascades take place. 在当前模型中,从Truck_companyDriver 没有定义关系,因此不会发生级联。


Note that modifying Driver such as: 请注意,修改Driver例如:

class Driver(Base):
    ...
    owner_id = Column(BigInteger, ForeignKey('truckcompany.id',
                                             ondelete='CASCADE'))

will not magically migrate the existing DB table and its constraints. 不会神奇地迁移现有的数据库表及其约束。 If you wish to take that route, you'll have to either migrate manually or using some tool. 如果您希望采用这种方式,则必须手动迁移或使用某些工具进行迁移

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IntegrityError: (1451, &#39;无法删除或更新父行:外键约束失败 (..)) - IntegrityError: (1451, 'Cannot delete or update a parent row: a foreign key constraint fails (..)) pymysql.err.IntegrityError:(1048,“列'dob'不能为空”) - pymysql.err.IntegrityError: (1048, “Column 'dob' cannot be null”) 无法删除或更新父行:外键约束失败 SQL 错误 - Cannot delete or update a parent row: a foreign key constraint fails SQL error IntegrityError(1452,'无法添加或更新子行:外键约束失败) - IntegrityError (1452, 'Cannot add or update a child row: a foreign key constraint fails) 如何修复 python 中的“pymysql.err.IntegrityError: (1048, ”Column 'ProTitre' cannot be null“)”错误? - How fix “pymysql.err.IntegrityError: (1048, ”Column 'ProTitre' cannot be null“)” error in python? 如何修复 IntegrityError:(psycopg2.errors.ForeignKeyViolation)更新或删除表“用户”违反外键约束 - How to fix IntegrityError: (psycopg2.errors.ForeignKeyViolation) update or delete on table "users" violates foreign key constraint Python Sqlalchemy mysql“无法添加或更新子行:外键约束失败” - Python Sqlalchemy mysql “Cannot add or update a child row: a foreign key constraint fails” 错误1452(23000):无法添加或更新子行:外键约束失败我无法修复 - ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails That I can't fix 无法添加或更新子行:Django生成的MySQL表上的外键约束失败 - Cannot add or update a child row: a foreign key constraint fails on a Django generated MySQL table IntegrityError:外键约束失败 - IntegrityError: FOREIGN KEY constraint failed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM