gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 16:24:24 24 4
gpt4 key购买 nike

我正在使用 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();

这会引发以下 SQL 错误,因为创建 table_atable_b 不存在:

ERROR 1215 (HY000): Cannot add foreign key constraint

有没有办法让 deploy() 函数预先检查外键依赖关系或指定首先插入的特定表?

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

最佳答案

事实证明,查询对顺序很敏感,因为定义第二个表时缺少索引。在描述的示例中,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 则无论 FOREIGN_KEY_CHECKS 设置为 0 还是 1,查询都会失败。

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

在表定义中,我使用架构加载器创建的样板代码下方的 sqlt_deploy_hook 来添加索引:

sub sqlt_deploy_hook {
my ($self, $sqlt_table) = @_;

$sqlt_table->add_index(name => 'table_b_idx_source_id', fields => ['source_id']);
}

感谢那些查看此问题或花时间考虑该问题的人。

关于mysql - 如何使用 DBIc Schema deploy() 定义表加载顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54328169/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com