我正在使用DBUnit和MySQL数据库。 DBUnit默认CLEAN_INSERT发出" DELETE FROM"没有WHERE子句的语句用于包含测试数据的表。使用MySQL时,对于具有外键约束的表会失败,并显示以下错误消息:
无法删除或更新父行:外键约束失败
在这种情况下,如何配置DBUnit以正确清理测试数据?
One possibility是禁用会话的外键检查。但是我不确定在DBUnit中最好的位置。我不想禁用对受测试代码本身的检查,但最多只能检查测试数据的设置/拆卸。
Deleting from a MySQL table with foreign key constraints提出了类似的问题,但是外键约束引用了一个不同的表。将ON DELETE CASCADE添加到外键定义的解决方案有效,但我不想改变测试的表定义。
显然这是MySQL中的missing feature。引自InnoDB and FOREIGN KEY Constraints:
与MySQL一样,在插入,删除或更新许多行的SQL语句中,InnoDB逐行检查UNIQUE和FOREIGN KEY约束。 ... InnoDB立即检查外键约束;检查不会延迟到事务提交。根据SQL标准,默认行为应该是延迟检查。也就是说,只有在处理完整个SQL语句后才会检查约束。在InnoDB实现延迟约束检查之前,有些事情是不可能的,例如删除使用外键引用自身的记录。
这是一个重现错误的SQL脚本:
create table foo (
foo_id varchar(255) NOT NULL,
other_foo_id varchar(255),
PRIMARY KEY (foo_id),
CONSTRAINT FK_other_foo_id FOREIGN KEY (other_foo_id) REFERENCES foo (foo_id)
);
insert into foo values ('foo-id-1',null);
insert into foo values ('foo-id-2','foo-id-1');
delete from foo;
删除语句失败,错误
错误1451(23000):无法删除或更新父行:外键约束失败(
coverage_integration_test
。foo
,CONSTRAINTFK_other_foo_id
FOREIGN KEY(other_foo_id
)参考foo
(foo_id
))
使用MySQL 5.5.40进行测试。