迁移问题:无法在laravel中添加外键约束

Posted

技术标签:

【中文标题】迁移问题:无法在laravel中添加外键约束【英文标题】:Migration Problem: Cannot add foreign key constraint in laravel 【发布时间】:2019-10-09 03:21:25 【问题描述】:

我正在尝试在 Laravel 5.7 中创建外键,但是当我使用 artisan 迁移我的表时,我抛出了以下错误:

照亮\数据库\查询异常:

SQLSTATE[HY000]:一般错误:1215 无法添加外键约束(SQL:更改表 gateway_transactions 添加约束 gateway_transactions_user_id_foreign 外键 (user_id) 在删除 CASCADE 时引用 users (id))

我的迁移:

    public function up()
    
        Schema::create('gateway_transactions', function (Blueprint $table) 
            $table->engine = "innoDB";
            $table->unsignedBigInteger('id', true);
            $table->integer('user_id')->unsigned();
            $table->enum('provider', \Parsisolution\Gateway\GatewayManager::availableDrivers());
            $table->decimal('amount', 15, 2);
            $table->integer('order_id')->nullable();
            $table->string('currency', 3)->nullable();
            $table->string('ref_id', 100)->nullable();
            $table->string('tracking_code', 50)->nullable();
            $table->string('card_number', 50)->nullable();
            $table->enum('status', \Parsisolution\Gateway\Transaction::availableStates())
                ->default(\Parsisolution\Gateway\Transaction::STATE_INIT);
            $table->string('ip', 20)->nullable();
            $table->json('extra')->nullable();
            $table->timestamp('paid_at')->nullable();
            $table->nullableTimestamps();
            $table->softDeletes();
        );
        Schema::table('gateway_transactions', function(Blueprint $table) 
            $table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE');
        );
    

用户迁移:

        Schema::create(config('access.table_names.users'), function (Blueprint $table) 
            $table->increments('id');
            $table->uuid('uuid');
            $table->string('first_name')->nullable();
            $table->string('last_name')->nullable();
            $table->string('email')->unique();
            $table->string('avatar_type')->default('gravatar');
            $table->string('avatar_location')->nullable();
            $table->string('password')->nullable();
            $table->timestamp('password_changed_at')->nullable();
            $table->tinyInteger('active')->default(1)->unsigned();
            $table->string('confirmation_code')->nullable();
            $table->boolean('confirmed')->default(config('access.users.confirm_email') ? false : true);
            $table->string('timezone')->nullable();
            $table->text('National_Code')->nullable();
            $table->char('phone_number', 11)->nullable()->unique();  
            $table->integer('phone_verify')->default(0);
            $table->char('mobile_number', 11)->nullable()->unique();  
            $table->integer('mobile_verify')->default(0);
            $table->text('state')->nullable();
            $table->text('city')->nullable();
            $table->text('address')->nullable();
            $table->text('path')->nullable();
            $table->char('postal_code', 10)->nullable();
            $table->timestamp('last_login_at')->nullable();
            $table->string('last_login_ip')->nullable();
            $table->rememberToken();
            $table->timestamps();
            $table->softDeletes();
        );

【问题讨论】:

user_id 的数据类型是什么?也许它是一个无符号大整数而不是无符号整数,数据类型必须完全匹配 @HCK 我改成 unsignedBigInteger,但又出现错误 ***.com/a/52902308/5928015 【参考方案1】:

为此更改您的代码:

public function up()

    Schema::create('gateway_transactions', function (Blueprint $table) 
        $table->engine = "innoDB";
        $table->unsignedBigInteger('id', true);
        $table->integer('user_id')->unsigned();
        $table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE');
        $table->enum('provider', \Parsisolution\Gateway\GatewayManager::availableDrivers());
        $table->decimal('amount', 15, 2);
        $table->integer('order_id')->nullable();
        $table->string('currency', 3)->nullable();
        $table->string('ref_id', 100)->nullable();
        $table->string('tracking_code', 50)->nullable();
        $table->string('card_number', 50)->nullable();
        $table->enum('status', \Parsisolution\Gateway\Transaction::availableStates())
            ->default(\Parsisolution\Gateway\Transaction::STATE_INIT);
        $table->string('ip', 20)->nullable();
        $table->json('extra')->nullable();
        $table->timestamp('paid_at')->nullable();
        $table->nullableTimestamps();
        $table->softDeletes();
    );

我认为 - 以下部分是我如何理解 Laravel 的工作方式。

由于您要将表创建到第一个 Schema 中,因此您必须将外键放入创建过程中。

问题是 Laravel Migration 会在应用代码之前验证一切是否正常,但阶段是函数 up()。因此,其中的所有内容都处于同一阶段。迁移认为您的 gateway_transactions 不存在,并且目前它没有验证一切正常。它会在代码存在时出现。

【讨论】:

你能告诉我们用户表的创建吗?我们需要查看用户表中 id 列的类型。 我不确定config('access.table_names.users') 将在您的数据库中创建什么名称。因此,我更改了 user_id 代码以反映您的用户数据库。它现在是一个整数。确保这部分 ->on('users') 与您的 users 表设置的名称相同。告诉我代码是否有效。 config('access.table_names.users')users。我更改了代码,但再次显示错误。我为另一个表创建外键但他们没有错误,只是为了这个表这个错误存在【参考方案2】:

外键列的类型必须与引用表完全相同。

如果Users表的ID是一个大整数:

$table->bigIncrements('id');

您的外键必须是:

$table->unsignedBigInteger('user_id');

然后迁移将正常工作。

【讨论】:

我改成unsignedBigInteger,但是又报错了

以上是关于迁移问题:无法在laravel中添加外键约束的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 迁移:无法添加外键约束

Laravel 表迁移:无法添加外键约束

无法添加外键约束 - Laravel 迁移错误

Laravel 迁移 - 一般错误:1215 无法添加外键约束

MySQL数据库的Laravel迁移“无法添加外键约束”错误

:完整性约束违规:1452 无法添加或更新子行:laravel 迁移中的外键约束失败