简体   繁体   English

SQLAlchemy删除级联完整性错误

[英]SQLAlchemy Delete Cascade Integrity Error

I am trying to delete an order from my database while deleting all ordereditems that relate to it. 我正在尝试从数据库中delete order ,同时删除ordereditems相关的所有ordereditems

with contextlib.closing(DBSession()) as session:
    try:
        returnedOrder = session.query(ORDER).filter_by(ORDERSID=orderID).first()
        session.delete(returnedOrder)
        session.commit()
    except exc.SQLAlchemyError, error:
        session.rollback()
        raise_database_error(error)
    else:
        return '1'

Here are the related classes (some items have been removed): 以下是相关的classes (已删除一些项目):

class ORDER(Base):
    __tablename__ = 'ORDERS'

    ORDERSID = Column(Integer, primary_key=True)
    ORDERSCOST = Column(Numeric(19, 4), nullable=False)

    ORDEREDITEM = relationship("ORDEREDITEM")  


class ORDEREDITEM(Base):
    __tablename__ = 'ORDEREDITEMS'
    __table_args__ = (
        Index('AK_ORDERSID_ITEMID', 'ORDERSID', 'ITEMSID', unique=True),
    )

    ORDEREDITEMSID = Column(Integer, primary_key=True)
    ITEMSID = Column(ForeignKey(u'ITEMS.ITEMSID'), nullable=False, index=True)
    ORDERSID = Column(ForeignKey(u'ORDERS.ORDERSID', ondelete=u'CASCADE'), nullable=False)
    ORDEREDITEMSQUANTITY = Column(Integer, nullable=False)

    ORDER = relationship(u'ORDER')

The SQL file: SQL文件:

create table ORDERS
(
 ORDERSID             int not null auto_increment,     
 ORDERSCOST           decimal(19,4) not null,
 primary key (ORDERSID)
);

create table ORDEREDITEMS
(
 ORDEREDITEMSID       int not null auto_increment,
 ORDERSID             int not null,
 ITEMSID              int not null,
 ORDEREDITEMSQUANTITY int not null,
 primary key (ORDEREDITEMSID),
 unique key AK_ORDERSID_ITEMID (ORDERSID, ITEMSID)
);

alter table ORDEREDITEMS add constraint FK_ORDER_ORDEREDITEM foreign key (ORDERSID)
  references ORDERS (ORDERSID) on delete CASCADE on update restrict;

When I run this, I get the error: 当我运行它时,我收到错误:

 (IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`my_database`.`ordereditems`,

 CONSTRAINT `FK_ORDER_ORDEREDITEM` FOREIGN KEY (`ORDERSID`) REFERENCES `ORDERS` (`ORDERSID`) ON DELETE CASCADE)') 

'UPDATE `ORDEREDITEMS` SET `ORDERSID`=%s WHERE `ORDEREDITEMS`.`ORDEREDITEMSID` = %s' (None, 3L)

When I perform the same operation directly on phpMyAdmin, it works as expected. 当我直接在phpMyAdmin上执行相同的操作时,它按预期工作。

A fully working example is usually most helpful, but I was able to filling in the missing parts from your example, and reproduce your exact problem-- the UPDATE statement that is attempted when trying to commit after delete. 一个完整的工作示例通常是最有帮助的,但我能够填充示例中缺少的部分,并重现您确切的问题 - 在删除后尝试提交时尝试的UPDATE语句。 (Fully working code here , all pure python, no SQL statements.) 这里完全可以使用代码,所有纯python,没有SQL语句。)

This question has been asked before many times, and I found the answer in this SO question. 这个问题在很多时候都被提出过,我在这个问题中找到了答案。

The fix is simply to change the ORDEREDITEM relationship from 修复只是为了改变ORDEREDITEM关系

ORDEREDITEM = relationship("ORDEREDITEM")

to

ORDEREDITEM = relationship("ORDEREDITEM", cascade="all,delete")

See the sqlalchemy docs here . 请在此处查看sqlalchemy文档。

Foreign key relationships involve a parent table that holds the central data values, and a child table with identical values pointing back to its parent. 外键关系涉及保存中心数据值的父表,以及具有指向其父级的相同值的子表。 The FOREIGN KEY clause is specified in the child table. FOREIGN KEY子句在子表中指定。

It will reject any INSERT or UPDATE operation that attempts to create a foreign key value in a child table if there is no a matching candidate key value in the parent table. 如果父表中没有匹配的候选键值,它将拒绝任何尝试在子表中创建外键值的INSERT或UPDATE操作。

SO Answers for Foreign Key Constraint OR Integrity Error 因此外键约束完整性错误的 答案

Update 更新

    create table ORDERS
    (
     ORDERSID             int not null auto_increment,     
     ORDERSCOST           decimal(19,4) not null,
     primary key (ORDERSID)
    );

    create table ORDEREDITEMS
    (
     ORDEREDITEMSID       int not null auto_increment,
     ORDERSID             int not null,
     ITEMSID              int not null,
     ORDEREDITEMSQUANTITY int not null,
     primary key (ORDEREDITEMSID),
     unique key AK_ORDERSID_ITEMID (ORDERSID, ITEMSID)
    );

    alter table ORDEREDITEMS add constraint FK_ORDER_ORDEREDITEM foreign key (ORDERSID)
      references ORDERS (ORDERSID) on delete CASCADE on update restrict;

    INSERT into ORDERS values(1,20.00);
    INSERT into ORDEREDITEMS values(1,1,1,2);

Now when you run above command in MySql your data is inserted successfully in Orders and ORDEREDITEMS DEMO1 现在,当您在MySql中运行上述命令时,您的数据将成功插入Orders和ORDEREDITEMS DEMO1中

So when does this error generates 那么什么时候会产生这个错误

(IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (IntegrityError)(1452,'无法添加或更新子行:外键约束失败

It's generated when your child (ORDEREDITEM) has invalid key of Parent(ie child contains invalid foreign key which is either deleted or does not exist from your Parent table) 当您的孩子(ORDEREDITEM)具有Parent的无效密钥时生成它(即子包含无效的外键,该外键被删除或从您的父表中不存在)

If i try to do this 如果我试着这样做

    INSERT into ORDEREDITEMS values(1,1,1,2);
    INSERT into ORDERS values(1,20.00);

I get error as OP got just by changing order of Insertion 我只是通过更改Insertion的顺序得到错误
even while deleting you can face this error 即使在删除时您也可能面临此错误

    INSERT into ORDERS values(1,20.00);

    DELETE FROM ORDERS
    WHERE ORDERSID=1;

    INSERT into ORDEREDITEMS values(1,1,1,2);

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM