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) referencescb_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 迁移自引用外键问题的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 迁移创建自定义外键

Laravel 迁移:创建 2 个表用户表和广告表(外键引用用户 ID)

Laravel 迁移错误号:150“外键约束格式不正确”

Laravel 迁移错误:150“外键约束格式不正确”

是否可以在 Laravel 的不同数据库中引用外键?

Laravel 向表中添加外键