当前位置: 首页 > 知识库问答 >
问题:

Laravel 5与外键相关的迁移错误

姬慎之
2023-03-14

这是通过使用包含以下内容的SQL转储移植旧项目来学习Laravel(特别是v5.x)的一种尝试:

CREATE TABLE IF NOT EXISTS `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `locationid` int(11) NOT NULL,
  `username` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
  `email` varchar(200) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
  `firstname` varchar(100) NOT NULL,
  `lastname` varchar(100) NOT NULL,
  `password` varchar(255) NOT NULL,
  `active` bit(1) DEFAULT b'1',
  `token` varchar(100) DEFAULT NULL,
  `token_created` timestamp NULL DEFAULT NULL,
  `role` varchar(45) NOT NULL DEFAULT 'user',
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`),
  UNIQUE KEY `username_UNIQUE` (`username`),
  KEY `location_idx` (`locationid`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

在垃圾堆的底部有一个与此特定表格相关的:

ALTER TABLE `user`
  ADD CONSTRAINT `location_userfk` FOREIGN KEY (`locationid`) REFERENCES `location` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

来自一对stackoverflow问题1、2、3;我修改了原始代码,将Schema::table的外键从Schema::create中拆分出来,并将unsigned()添加到每个字段:

public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table->increments('id');
        $table->integer('locationid')->unsigned();
        // $table->foreign('locationid')->references('id')->on('location');
        $table->string('username', 60)->unique();
        $table->string('email', 200)->unique();
        $table->string('firstname', 100);
        $table->string('lastname', 100);
        $table->string('password', 255);
        $table->boolean('active')->default(TRUE);
        $table->string('role', 45)->default('user');
        // $table->string('token', 255)->nullable()->default(NULL);
        // $table->string('token_create')->nullable()->default(NULL);
        $table->rememberToken();
        $table->timestamps();
    });

    Schema::table('users', function(Blueprint $table) 
    {
        $table->foreign('locationid')->references('id')->on('location');
    });
}

但在使用新创建的空DB进行迁移时,仍然会出现错误:

exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint' in /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php:358
Stack trace:
#0 /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php(358): PDOStatement->execute(Array) etc...

Next exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[HY000]: General err
or: 1215 Cannot add foreign key constraint (SQL: alter table `users` add constraint users_loca
tionid_foreign foreign key (`locationid`) references `location` (`id`))' in /home/vagrant/proj
ects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php:614   
Stack trace:                                                                                  
#0 /home/vagrant/projects/communityfuturesbc/vendor/laravel/framework/src/Illuminate/Database/Connection.php(570): Illuminate\Database\Connection->runQueryCallback('alter table `us...', Ar
ray, Object(Closure))

根据MySQL,这意味着:

Error: 1215 SQLSTATE: HY000 (ER_CANNOT_ADD_FOREIGN)
Message: Cannot add foreign key constraint                                         

在这之后,我无法再次回滚或迁移,而不会得到另一种关于数据库中已经存在的users表的错误,因此每次我尝试上述代码的一个版本时,我都会删除我的数据库。

我确信在修复这个问题后,它会出现在所有其他表中,这些表都是相似的或有多个外键,所以希望无论修复什么,它都能对其余的表起作用。

共有3个答案

施德元
2023-03-14

我也有同样的问题,我做了什么?

易于理解的在迁移文件中,请尝试以下操作。。。。

public function up()
{

Schema::create('location', function(Blueprint $table)
{
    $table->increments('id');
    ...other attributes... 
    $table->rememberToken();
    $table->timestamps();
});

Schema::create('users', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('locationid')->unsigned();
    $table->string('username', 60)->unique();
    $table->string('email', 200)->unique();
    $table->string('firstname', 100);
    $table->string('lastname', 100);
    $table->string('password', 255);
    $table->boolean('active')->default(TRUE);
    $table->string('role', 45)->default('user');
    // $table->string('token', 255)->nullable()->default(NULL);
    // $table->string('token_create')->nullable()->default(NULL);
    $table->rememberToken();
    $table->timestamps();
});

Schema::table('users', function(Blueprint $table) 
{
    $table->foreign('locationid')->references('id')->on('location');
});}

:)

郭远
2023-03-14

该错误是由尝试引用不存在的列的迁移引起的。为了防止此问题,请在执行外键创建之前创建引用的列。

要创建具有依赖关系的表结构,您可以按照正确的顺序创建迁移文件,或者将所有迁移放入一个大文件中,或者至少创建所有不带外键的表,并创建另一个最终执行键创建的文件。请尽量少,这仅在您想要重新编写存量数据结构或想要修复迁移顺序时才是必要的。否则请使用php artisan make:迁移命令。

贝镜
2023-03-14

您必须更改迁移顺序

|-database/
|--migrations/
|---2015_02_02_141725_create_users_table.php
|---2015_03_01_234626_create_locations_table.php

应该是:

|-database/
|--migrations/
|---2015_01_01_234626_create_locations_table.php
|---2015_02_02_141725_create_users_table.php

最后:

php artisan migrate
 类似资料:
  • Laravel5.6运行于:PHP7.2,MariaDB 10.3 当我想为我的表设置外键时,我只是不断地犯这个错误。 在其他表中,由Laravel本身定义的所有id变量和无符号自动增量 所以,我的迁移是这样的: 错误如下所示: SQLSTATE[42000]:语法错误或访问冲突:1064您的SQL语法有错误;检查与您的MariaDB服务器版本对应的手册,以了解在LINE 1(SQL:alter

  • 在Laravel 5.1中,我可以看到表列关系可以通过两种方式设置: 1) 在迁移表中定义外键。 2)定义模型中的雄辩关系。 我已经阅读了文件,我仍然对以下内容感到困惑: > 我是需要同时使用这两个还是只需要1个? 两者同时使用有错吗?还是让它变得多余或者引起冲突? 使用有说服力的关系而不在迁移列中提及外键有什么好处? 有什么区别? 这些是我现在掌握的密码。我仍然不清楚是否需要删除迁移文件中设置的

  • 我有两个表,事务表和付款表,它们在过去的迁移中已经存在。当我试图在它们之间建立一个透视表时,只会得到事务外键的一个错误。“payments”表上的另一个外键创建得很好。这绝对让我感到困惑,我之前关于这个错误的讨论都没有解决这个问题。 错误(参考,MAccounting是数据库的名称): *尽管错误似乎说,payment_transaction表创建成功,以及支付表的外键;唯一中断的是交易的外键。

  • 我必须定义code.Spatial类,如主键和codels.LScharacteristic codels.PlannedUsing,如外键。当我尝试migrate:ProgrammingError:ERROR:foreign key约束中指定的id列不存在时,我遇到了这个问题。 UPD完整日志:上述异常是以下异常的直接原因: 回溯(最后一次调用):文件“manage.py”,第23行,从命令行执

  • 我花了一整天的时间试图弄清楚下面的迁移发生了什么。 这是表的迁移。我的想法是使用“id_stays_abroad”和“user_id”作为外键。 这是添加外键的另一个迁移 当我运行php artisan迁移时,我遇到了以下错误: SQLSTATE[HY000]:一般错误:1215无法添加外键约束(SQL:alter table

  • 我有多个迁移,但我认为与这个问题相关的两个迁移是“作业”和“会话”迁移。 作业迁移