Laravel 4迁移问题中的外键问题

时间:2013-06-04 22:46:44

标签: mysql laravel laravel-4

我刚刚创建了一个新的Laravel 4项目,我发现架构生成器的外键方面发生了奇怪的事情。如果我在任何迁移中使用->foreign()方法,我会抛出MySQL错误150和一般错误1005.根据laravel.com/docs的文档,底部的两个场景应该有效吗?有谁知道他们为什么不这样做?

以下工作正常:

    Schema::create('areas', function($table)
    {
        $table->engine ='InnoDB';
        $table->increments('id');

        $table->integer('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });

但这两个不起作用:

    Schema::create('areas', function($table)
    {
        $table->engine ='InnoDB';
        $table->increments('id');

        $table->foreign('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });

    Schema::create('areas', function($table)
    {
        $table->engine ='InnoDB';
        $table->increments('id');

        $table->integer('region_id');
        $table->foreign('region_id')->references('id')->on('regions');

        $table->string('name', 160);
        $table->timestamps();
    });

5 个答案:

答案 0 :(得分:53)

检查您的id类型。 Laravel 4使用int(10)unsigned创建一个增量id。 如果您创建一个基本整数并尝试在其上放置一个外键,它将失败。

正如this link文档中所建议的那样,您应该使用$table->unsignedInteger(YOUR_ID_NAME);创建外部ID以使其正常工作。

答案 1 :(得分:7)

此问题还有一些答案"General error: 1005 Can't create table" Using Laravel Schema Build and Foreign Keys

其中列出的答案摘要,包括我的答案:

  1. 外键通常需要InnoDb,因此请设置默认引擎,或明确指定 $table->engine = 'InnoDB'; 如果您的表已经创建并默认为MyISAM,您可能需要更改它。

  2. 外键需要引用的表存在。在创建密钥之前,请确保在先前的迁移中创建了引用的表。考虑在单独的迁移中创建密钥以确保。

  3. 外键要求数据类型一致。检查引用的字段是否是相同的类型,无论是有符号还是无符号,它的长度是否相同(或更小)。

  4. 如果要在手动编码迁移和使用生成器之间切换,请确保检查正在使用的ID类型。 Artisan默认使用 incrementments(),但Jeffrey Way似乎更喜欢整数('id',true)

答案 2 :(得分:5)

前一天有同样的问题。

问题的根源是:带有外键的列必须与该键的类型相同。 你有不同的类型: INT / UNSIGNED INT

这使得ID成为UNSIGNED INT

$table->increments('id');

这使得region_id成为INT

$table->integer('region_id')->references('id')->on('regions'); 

要解决此问题,请将region_id设为UNSIGNED INT

$table->integer('region_id')->unsigned()->references('id')->on('regions'); 
                              ^^^^^^^^^ note here

Laravel的文档mention有关于此的内容:

  

注意:创建引用递增整数的外键时,请记住始终使外键列无符号。

答案 3 :(得分:2)

它有效,但有时候你必须要小心,并试着了解幕后发生的事情。

正如我在评论中所说。当您第一次运行迁移而不创建相关列时,Laravel迁移服务会创建您的表,然后,当您尝试再次迁移时,它将始终显示错误,表明该表已存在。

因此,您只需drop table areas并再次运行php artisan migrate即可解决所有问题。

编辑:

我刚刚在这里创建了你的迁移(下面)并且它有效。

正如您所看到的,我没有使用MySQL,因此它必定是MySQL的问题。检查MySQL外键文档,看看您的元数据是否符合InnoDB要求:http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html

<?php

use Illuminate\Database\Migrations\Migration;

class CreateAreasTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('regions', function($table)
         {
             // $table->engine = 'InnoDB';
             $table->increments('id');
             $table->string('name', 160)->unique();
             $table->timestamps();
        });

        Schema::create('areas', function($table)
        {
            // $table->engine ='InnoDB';
            $table->increments('id');

            $table->integer('region_id');
            $table->foreign('region_id')->references('id')->on('regions');

            $table->string('name', 160);
            $table->timestamps();
        });     
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
    Schema::drop('areas');
    Schema::drop('regions');
    }

}

enter image description here

答案 4 :(得分:1)

antonio carlos是对的,请确保您首先创建了外键的参考表。

尝试首先迁移没有外键的表,然后进行另一次迁移,分配外键。在这种状态下,laravel确定引用键是存在的。你不必在工匠错误中丢桌。