Laravel 迁移自引用外键问题
Posted
技术标签:
【中文标题】Laravel 迁移自引用外键问题【英文标题】:Laravel migration self referencing foreign key issue 【发布时间】:2013-08-27 22:55:02 【问题描述】:您好,我在使用迁移架构生成器创建表时遇到问题。 具有自引用外键的表出现问题。 这是产生错误的代码:
Schema::create('cb_category', function($table)
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
);
这是错误:
SQLSTATE[HY000]: General error: 1005 Can't create table 'eklik2.#sql-7d4_e' (errno: 150) (SQL: alter table `cb_cate
goryadd constraint cb_category_parent_id_foreign foreign key (
parent_id) references
cb_category(
id`) 在德尔
更新级联上的级联)(绑定:数组(
))
[PDO异常] SQLSTATE[HY000]:一般错误:1005 无法创建表 'eklik2.#sql-7d4_e' (errno: 150)
有什么想法吗?
【问题讨论】:
【参考方案1】:您必须将其分解为两个 Schema 块,一个创建列,另一个添加 FK。 mysql不能同时做这两件事。
【讨论】:
我在 2 个语句中打破了它,无论如何错误仍然存在: Schema::create(...); Schema::table('cb_category', function($table) $table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')- >onDelete('cascade'); ); 通过中断解决。这是代码: Schema::create('cb_category', function($table)... ); $dbh = DB::getPdo(); $dbh->query("ALTER TABLE cb_category ADD CONSTRAINT fk_cb_category_parent_id FOREIGN KEY (parent_id) REFERENCES cb_category (id) ON DELETE NO ACTION ON UPDATE NO ACTION");【参考方案2】:我可能为时已晚,但官方文档声称外键,如果是整数,必须是->unsigned();
http://laravel.com/docs/4.2/schema#foreign-keys
注意:创建引用递增的外键时 整数,请记住始终使外键列无符号。
此外,如果您(和我一样)拼错 unsigned()
,Artisan 也不会失败,而且我已经花了好几个小时试图找出未创建密钥的原因。
所以有两件事:
1. 在递增整数的情况下,始终使外键列无符号
2.检查unsigned()
的拼写
【讨论】:
【参考方案3】:两个查询有效:
Schema::create('cb_category', function($table)
$table->integer('id')->primary()->unique()->unsigned();
$table->integer('parent_id')->nullable();
);
Schema::table('cb_category', function (Blueprint $table)
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
);
【讨论】:
这似乎是正确的答案。工作得很好,很有意义。【参考方案4】:对于 Laravel 8 来说也是一种较晚的响应,但可能是一种更惯用的方式:
use App\Models\CbCategory;
...
Schema::create("cb_category", function(Blueprint $table)
$table->id();
$table->foreignIdFor(CbCategory::class, "parent_id")
->constrained()
->cascadeOnUpdate()
->cascadeOnDelete()
->nullable();
);
请注意:我在这里猜到了
CbCategory
的类名。直接使用类引用(而不是以前的表名字符串)使您的静态代码检查器能够了解未来的类名更改。 此外,parent_id
列名称中的_id
-后缀也很重要。
愿以下资源满足您对知识的渴望:
id()
: https://laravel.com/docs/8.x/migrations#column-method-id
foreignIdFor()
: https://laravel.com/api/8.x/Illuminate/Database/Schema/Blueprint.html
cascadeOnDelete()
& cascadeOnUpdate()
: https://laravel.com/api/8.x/Illuminate/Database/Schema/ForeignKeyDefinition.html
【讨论】:
【参考方案5】:Schema::create('cb_category', function (Blueprint $table)
$table->increments('id')->unsigned();
$table->integer('domain_id')->unsigned();
$table->foreign('domain_id')->references('id')->on('cb_domain');
$table->integer('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('cb_category')->onUpdate('cascade')->onDelete('cascade');
$table->string('name');
$table->integer('level');
);
试试这个
【讨论】:
这与问题中的问题相同。表在创建时不能引用自身,因为在创建表时不存在可引用的表,【参考方案6】:我认为您有另一个引用您要创建的当前表的表。 我遇到了这个问题,删除了那个表,我的问题就解决了
【讨论】:
以上是关于Laravel 迁移自引用外键问题的主要内容,如果未能解决你的问题,请参考以下文章