SQLAlchemy删除级联完整性错误

时间:2015-04-04 04:13:14

标签: python mysql sqlalchemy sql-delete

我正在尝试从我的数据库中delete order,同时删除与其相关的所有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'

以下是相关的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')

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;

当我运行时,我收到错误:

 (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)

当我直接在phpMyAdmin上执行相同的操作时,它按预期工作。

2 个答案:

答案 0 :(得分:6)

一个完整的工作示例通常是最有帮助的,但我能够填充示例中缺少的部分,并重现您确切的问题 - 在删除后尝试提交时尝试的UPDATE语句。 (完全正常工作的代码here,所有纯python,没有SQL语句。)

此问题曾多次被问到,我在this问题中找到答案。

修复只是从

更改ORDEREDITEM关系
ORDEREDITEM = relationship("ORDEREDITEM")

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

请参阅sqlalchemy docs here

答案 1 :(得分:0)

  

外键关系涉及包含中心数据值的父表,以及具有指向其父级的相同值的子表。 FOREIGN KEY子句在子表中指定。

     

如果父表中没有匹配的候选键值,它将拒绝任何尝试在子表中创建外键值的INSERT或UPDATE操作。

SO Answers for Foreign Key ConstraintIntegrity Error

<强>更新

    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);

现在,当您在MySql中运行上述命令时,您的数据已成功插入订单和ORDEREDITEMS DEMO1

那么这个错误何时生成

  

(IntegrityError)(1452,'无法添加或更新子行:外键约束失败

当您的孩子(ORDEREDITEM)具有Parent的无效密钥时生成(即子包含无效的外键,该外键已从父表中删除或不存在)

如果我尝试这样做

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

我通过改变插入顺序来获得错误OP即使在删除时你也可能面临这个错误

    INSERT into ORDERS values(1,20.00);

    DELETE FROM ORDERS
    WHERE ORDERSID=1;

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