【问题标题】:PHP Laravel PDOException General error referencing column and referenced column in a foreign key constraint are incompatiblePHP Laravel PDOException 一般错误引用列和外键约束中的引用列不兼容
【发布时间】:2019-06-23 04:40:33
【问题描述】:

我目前正在通过终端在 Laravel 中进行迁移,在尝试使用 php artisan migrate 时出现这两个错误;我将在下面打印错误:

Exception trace:

  1   PDOException::("SQLSTATE[HY000]: General error: 3780 Referencing column 'room_id' and referenced column 'id' in foreign key constraint 'contacts_room_id_foreign' are incompatible.")
      /Users/shaquilenoor/Desktop/chatapi/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

  2   PDOStatement::execute()
      /Users/shaquilenoor/Desktop/chatapi/vendor/laravel/framework/src/Illuminate/Database/Connection.php:458

根据异常跟踪中包含的代码,问题似乎在以下代码中:

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateContactsTable extends Migration
{
    public function up()
    {
        Schema::create('contacts', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user1_id');
            $table->unsignedInteger('user2_id');
            $table->integer('room_id')->unique();
            $table->timestamps();
            $table->foreign('room_id')->references('id')->on('rooms');
            $table->foreign('user1_id')->references('id')->on('users');
            $table->foreign('user2_id')->references('id')->on('users');
        });
    }

    public function down()
    {
        Schema::dropIfExists('contacts');
    }
}

关于如何解决的任何想法?

【问题讨论】:

  • $table->id(); //UNSIGNED BIG INTEGER 所以$table->unsignedBigInteger('room_id')

标签: php laravel terminal


【解决方案1】:

在这种情况下,room_id 应该是无符号的。试试这个:

 public function up()
    {
        Schema::create('contacts', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user1_id');
            $table->unsignedInteger('user2_id');
            $table->integer('room_id')->unique()->unsigned();
            $table->timestamps();
            $table->foreign('room_id')->references('id')->on('rooms');
            $table->foreign('user1_id')->references('id')->on('users');
            $table->foreign('user2_id')->references('id')->on('users');
        });
    }

【讨论】:

    【解决方案2】:

    这是由于在创建房间表之前设置了外键。您可以通过执行以下操作来解决此问题。

    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    
    class CreateContactsTable extends Migration
    {
        public function up()
        {
            Schema::disableForeignKeyConstraints();
            Schema::create('contacts', function (Blueprint $table) {
                $table->increments('id');
                $table->unsignedInteger('user1_id');
                $table->unsignedInteger('user2_id');
                $table->integer('room_id')->unique();
                $table->timestamps();
                $table->integer('room_id')->unsigned();
                $table->integer('user1_id')->unsigned();
                $table->integer('user2_id')->unsigned();
                $table->foreign('room_id')->references('id')->on('rooms');
                $table->foreign('user1_id')->references('id')->on('users');
                $table->foreign('user2_id')->references('id')->on('users');
            });
            Schema::enableForeignKeyConstraints();
        }
    
        public function down()
        {
            Schema::disableForeignKeyConstraints();
            Schema::dropIfExists('contacts');
            Schema::enableForeignKeyConstraints();
        }
    }
    
    

    【讨论】:

      【解决方案3】:

      如果您使用的是 Laravel 5.8,则新迁移已更改为大增量,因此要修复引用错误,只需将 integer 更改为 bigInteger,对于示例:

      $table->integer('user_id')->unsigned()->index();
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
      

      将改为:

      $table->bigInteger('user_id')->unsigned()->index();
      $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
      

      【讨论】:

        【解决方案4】:

        要么更改原始迁移 来自

        大增量()

        只是

        增量();


        或者在你的外键列做

        大整数()

        而不是

        整数()

        【讨论】:

        • 请在您的答案中添加一些解释,以便其他人可以从中学习 - 为什么需要这样做?
        【解决方案5】:

        Laravel 6.0 中,迁移与提到的 @Payam Khaninejad 相同。即

        $table->bigInteger('user_id')->unsigned()->index();
        

        我正在为 Laravel 6.0 更新该内容,因为我正在关注一个显示相同错误的旧教程。

        【讨论】:

          【解决方案6】:

          同样在 laravel 7.x 中你可能需要改变:

          $table->increments('id'); // UNSIGNED INTEGER
          // to 
          $table->id(); // UNSIGNED BIGINT
          

          【讨论】:

          • 请在您的答案中添加一些解释,以便其他人可以从中学习 - 此更改与给定的错误消息有何关系?
          【解决方案7】:

          这似乎是在旧版本中迁移的表的问题。我遇到了同样的问题,在我的情况下,我为每个外键使用了两种不同类型的声明。 “整数”和“无符号整数”

                  $table->integer('webcam_id');
                  $table->unsignedInteger('user_id');
               
          
                  $table->foreign('webcam_id')
                      ->references('id')
                      ->on('webcam');
          
                  $table->foreign('user_id')
                      ->references('id')
                      ->on('users');
          

          【讨论】:

            【解决方案8】:

            用户表

            $table->increments('id');
            

            联系人表

            $table->integer('user_id')->unsigned();  //adding unsigned() here, will fix the error
            $table->foreign('user_id')->references('id')->on('users');
            

            【讨论】:

              【解决方案9】:

              外键必须与引用id相同, 从而改变

              $table->integer('room_id')->unique();
              

              $table->unsignedBigInteger('room_id')->unique();
              

              它成功了。

              PS:你会得到另一个错误

              SQLSTATE[42S01]:基表或视图 已存在:1050 表...

              只需删除表并运行php artisan migrate

              【讨论】:

                【解决方案10】:

                我最近在迁移创建具有外键约束的表时遇到了这个问题。我发现它必须与桌子上使用的排序规则有关。我们的 DB 模式加载了一个模式文件,该文件的表排序规则设置为 utf8mb4_0900_ai_ci。看起来 Laravel 默认使用 utf8mb4_unicode_ci

                我通过在创建过程中使用$table->collation = 'YOUR_COLLATION_VALUE' 设置表的排序规则解决了这个问题

                【讨论】:

                  【解决方案11】:

                  对于 Laravel 8.x,将 $table->integer('user_id')->unsigned()->index(); 更改为: $table->unsignedBigInteger('user_id'); ,因为这与 id() 数据类型兼容。

                  【讨论】:

                    【解决方案12】:

                    在您的房间迁移中,更改 id

                    $table->id();
                    

                    它会自动创建名为 'id' 的 bigInteger

                    然后在您的联系人迁移中,使用

                    $table->bigInteger('room_id')->references('id')->on('rooms');
                    

                    其他外键也是如此,只需按照上面的代码即可。

                    至少这种语法适用于 laravel 8

                    【讨论】:

                      猜你喜欢
                      • 2020-05-22
                      • 2020-08-01
                      • 2020-12-14
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2021-06-01
                      • 2016-12-20
                      • 2020-03-25
                      相关资源
                      最近更新 更多