CodeIgniter 4有一个方便的迁移和播种器解决方案。没有使用外键,一切都运行得很完美。但是当我使用外键时,我得到“无法添加外键”。
这是因为发生的顺序:
快速示例:
table bar
-------------------
| id | name | fooid |
FOREIGN KEY fooid REFERENCES foo.id
table foo
----------
| id | name|
因此,当我现在运行php spark migrate
或php spark migrate:refresh
时,无法设置外键,因为创建了bar
表,但引用的foo
表尚不存在。
从技术上讲,我可以在迁移后运行一个单独的函数,但我喜欢php spark migrate
的一个命令,一切都完成了。
解决这个问题的正确方法是什么?
这是我创建表时创建的代码:
CREATE TABLE `bar` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
`fooid` int(11) UNSIGNED NOT NULL,
CONSTRAINT `pk_bar` PRIMARY KEY(`id`),
CONSTRAINT `bar_fooid_foreign` FOREIGN KEY(`fooid`) REFERENCES `foo` (`id`) ON DELETE SET NULL,
KEY `fooid` (`fooid`)
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci;
CREATE TABLE `foo` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
CONSTRAINT `pk_foo` PRIMARY KEY(`id`),
) DEFAULT CHARACTER SET = utf8 COLLATE = utf8_general_ci;
附录
我认为我找到了问题的方向。从评论中注意到,它是正确的,但表的创建顺序不正确。这可以通过更改文件名中的时间戳来修复,这样foo
会在bar
之前创建。但由于这不是修复问题,我发现了其他一些东西:这是我用来迁移bar
的代码:
class Bar extends Migration
{
public function up()
{
$fields = [
'id' => [
'type' => 'int',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
],
'name' => [
'type' => 'varchar',
'constraint' => 255,
'default' => null,
],
'fooid' => [
'type' => 'int',
'constraint' => 11,
'unsigned' => true,
],
];
$this->forge->addField($fields);
$this->forge->addPrimaryKey('id');
$this->forge->addKey('fooid');
$this->forge->addForeignKey('fooid', 'foo', 'id', '', 'SET NULL');
$this->forge->createTable('bar');
}
public function down()
{
$this->forge->dropTable('bar');
}
}
这将生成一个fooid int(11) UNSIGNED NOT NULL
。问题是,foodid
不能是null
,但fk在删除时将值设置为null
。
但是...字段的null
的默认值是'null' => true
,即使我手动添加它,它也不会生成可为空的字段。
1条答案
按热度按时间sshcrbum1#
只需 * 重命名 * 移植时间戳前缀,使
foo
的表创建先于bar
的表创建。例如,如果移植文件名如下:重命名它们的迁移时间戳前缀,因为引用的表(
foo
)优先。最后,重新运行挂起的迁移。
php spark migrate
。附录1
参照您新编辑的问题描述,将
foo
的建表查询移动到bar
的建表查询之前,即:附录2
2022 - 02 - 16 - 101819_创建一个文件名为foomigration.php的文件
2022 - 04 - 22 - 101819_创建条迁移. php