如何使用DBIc Schema deploy()定义表加载顺序

时间:2019-01-23 13:17:49

标签: mysql perl foreign-keys dbix-class

我正在使用DBIc模式包装数据库模式,以帮助对代码进行单元测试。

基于原始数据库,我使用dbidump从数据库生成模式:

dbicdump -o dump_directory=./lib -o components='["InflateColumn::DateTime"]' -o debug=1 Test::Schema 'dbi:mysql:dbname=mcdowall_test' 'test'

有2个InnoDB表table_atable_b。问题是table_a在表table_b上具有外键约束:

CREATE TABLE `table_b` (
  `table_b_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `source_id` INT UNSIGNED NULL,
  PRIMARY KEY (`table_b_id`),
  KEY (`source_id`))
ENGINE = InnoDB;

CREATE TABLE `table_a` (
  `table_a_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `source_id` INT UNSIGNED NULL DEFAULT NULL,
  PRIMARY KEY (`table_a_id`),
  KEY (`table_a_id`),
  CONSTRAINT `fk_ab`
    FOREIGN KEY (`source_id`)
    REFERENCES `table_b` (`source_id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

这意味着在测试过程中使用deploy()安装架构时,它将以字母顺序安装表:

use Test::Schema

my $schema = Test::Schema->connect($dsn, $user, $pass, \%opts);
$schema->deploy();

由于创建table_btable_a不存在,因此会引发以下SQL错误:

ERROR 1215 (HY000): Cannot add foreign key constraint

是否可以通过获取deploy()函数来预先检查外键依赖关系或指定要首先插入的特定表?

理想情况下,应先安装table_b,然后再安装table_a

1 个答案:

答案 0 :(得分:0)

事实证明,查询对订单敏感,因为在定义第二张表时缺少索引。在描述的示例中,table_a的定义是相同的,但是table_b的定义是:

CREATE TABLE `table_b` (
  `table_b_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `source_id` INT UNSIGNED NULL,
  PRIMARY KEY (`table_b_id`))
ENGINE = InnoDB;

table_b然后table_a的顺序运行时,一切都很好。如果按照table_a然后table_b的顺序进行调用,因为source_id的定义中table_b上缺少索引,则查询是否会失败{ {1}}设置为0或1。

通过在DBIc中打开debug()设置以查找其运行的查询,然后在Percona博客上使用此post来减少问题并找到答案,从而找到了答案。

然后在表定义中,使用模式加载程序创建的样板代码下方的FOREIGN_KEY_CHECKS添加索引:

sqlt_deploy_hook

感谢那些看过这个问题或花了一些时间来考虑这个问题的人。