【问题标题】:Laravel migration self referencing foreign key issueLaravel 迁移自引用外键问题
【发布时间】: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)

有什么想法吗?

【问题讨论】:

    标签: php mysql foreign-keys migration laravel


    【解决方案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-后缀也很重要。


      愿以下资源满足您对知识的渴望:

      【讨论】:

        【解决方案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】:

        我认为您有另一个引用您要创建的当前表的表。 我遇到了这个问题,删除了那个表,我的问题就解决了

        【讨论】:

          猜你喜欢
          • 2014-08-09
          • 2014-03-11
          • 1970-01-01
          • 2020-08-01
          • 2015-01-13
          • 2013-05-31
          • 2015-03-31
          • 1970-01-01
          • 2020-06-05
          相关资源
          最近更新 更多