CodeIgniter 4 為遷移和播種器提供了方便的解決方案。如果不使用外鍵,一切都運行良好。但是當我使用外鍵時,我得到“無法添加外鍵”。
這是因為發生的順序:
快速示例:
table bar
-------------------
| id | name | fooid |
FOREIGN KEY fooid REFERENCES foo.id
table foo
----------
| id | name|
所以當我現在運行php spark migrate還是因為表已經創建,但是參考的表還不存在,php spark migrate:refresh所以無法設定外鍵。barfoo
從技術上講,我可以在遷移后運行一個單獨的函式,但我喜歡一個命令,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 將值設定為nullon delete。
但是......一個欄位的默認值null是'null' => true,即使我手動添加它,它也不會生成可為空的欄位。
uj5u.com熱心網友回復:
只需重命名您的遷移時間戳前綴,以便表創建foo在bar. 例如,如果遷移檔案名如下:
app/Database/Migrations/2022-02-16-101819_CreateBarMigration.php
app/Database/Migrations/2022-04-22-101819_CreateFooMigration.php ?
重命名它們的遷移時間戳前綴,因為參考的表 ( foo) 先出現。
app/Database/Migrations/2022-04-22-101819_CreateBarMigration.php
app/Database/Migrations/2022-02-16-101819_CreateFooMigration.php ?
最后,重新運行掛起的遷移。php spark migrate.
附錄 1
參考您新編輯的問題描述,將表創建查詢foo移至. IE:bar
CREATE TABLE `foo` ( ...)
CREATE TABLE `bar` ( ...)
附錄 2
2022-02-16-101819_CreateFooMigration.php
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateFooMigration extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
],
'name' => [
'type' => 'VARCHAR',
'constraint' => '100',
]
]);
$this->forge->addKey('id', true);
$this->forge->createTable('foo');
}
public function down()
{
$this->forge->dropTable('foo');
}
}
2022-04-22-101819_CreateBarMigration.php
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateBarMigration extends Migration
{
public function up()
{
$this->forge->addField([
'id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'auto_increment' => true,
],
'name' => [
'type' => 'VARCHAR',
'constraint' => '100',
],
'foo_id' => [
'type' => 'INT',
'constraint' => 11,
'unsigned' => true,
'null' => true,
],
]);
$this->forge->addKey('id', true);
$this->forge->addForeignKey('foo_id', 'foo', 'id', 'CASCADE', 'RESTRICT' );
$this->forge->createTable('bar');
}
public function down()
{
$this->forge->dropTable('bar');
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/467571.html
標籤:php mysql 代码点火器 数据库迁移 codeigniter-4
下一篇:獲取非重復記錄的最大值
