Laravel 迁移外键取决于种子数据

Posted

技术标签:

【中文标题】Laravel 迁移外键取决于种子数据【英文标题】:Laravel migration foreign key depending on seed data 【发布时间】:2015-03-16 07:24:48 【问题描述】:

我需要通过迁移和植入数据库来更新现有的 Laravel 应用程序。

我有一张如下表:

项目

身份证 姓名

我想将数据库编辑成如下所示:

项目

身份证 姓名 type_id(新列)

类型(新表)

身份证 姓名

type_idtypes 表的非空外键。

types 表将在以下操作中使用 Laravel 播种器播种。这个播种器将在每次应用程序更新后被调用,并截断/重新插入一些“静态”数据,这些数据只会随着应用程序的更新而改变。它的配置方式类似于Laravel : Migrations & Seeding for production data,用于本地/生产差异

在本地数据库上从头开始时一切正常。但是在生产数据库上,已经有很多记录了。由于是非空键,所以推送到这个数据库时迁移失败(实际上是那个数据库的副本用于测试)

作为迁移解决方案,我想将第一个 type 记录添加到每个现有 item 中,但我无法在迁移期间设置外键,因为items 表在这个阶段是空的,在播种之前我不能让它空着,因为迁移没有通过。

有些事情我想:

在整个更新过程中禁用对数据库的外键检查,但我更喜欢一种解决方案,它允许我简单地将我的存储库推送到服务器并启动我的自动部署脚本(本质上调用 artisan migrate 后跟 artisan db :种子)。 在创建 types 表后立即从迁移中调用播种器,但我不确定这是一个好习惯

我该怎么办?

编辑:这是我使用@lukasgeiter 答案的工作迁移代码:

public function up()

    DB::statement('SET FOREIGN_KEY_CHECKS = 0');

    Schema::table('items', function(Blueprint $table)
    
        $table->integer('type_id')->unsigned()->index()->after('name');
    );

    DB::update('update items set type_id = 1');

    Schema::table('items', function(Blueprint $table)
    
        $table->foreign('type_id')->references('id')->on('types');

        // Here I do other stuff to this table
    );

    DB::statement('SET FOREIGN_KEY_CHECKS = 1');

【问题讨论】:

【参考方案1】:

您可以使用 DB::statement 和 SQL 在迁移中禁用外键检查。

DB::statement('SET FOREIGN_KEY_CHECKS = 0');
// add column
DB::statement('SET FOREIGN_KEY_CHECKS = 1');

【讨论】:

但是我什么时候运行我的播种机?如果我在添加列后重新启用外键而不做任何其他事情,它将失败(仍然不允许 null) 我以为你会用有效值播种 type_id 是的没错我会设置正确的外键但是此时types表还是空的,只会在下一步部署时做种子(artisan db:seed) 我仍然认为这应该可行。首先,您关闭密钥检查,创建列并再次打开它们。然后(播种时)播种types 表,然后更新items 中的type_id。我错了吗? 不,是我错了=| .我认为以这种方式处理数据库会导致错误,但它实际上按预期工作。我将在问题中添加我的工作代码。谢谢!

以上是关于Laravel 迁移外键取决于种子数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 laravel 迁移和种子正确处理数据库数据更改

Laravel Dusk:迁移和种子测试数据库一次

迁移后的 Laravel 种子

无法使用 laravel 数据库迁移创建外键

Laravel 数据库迁移外键错误

Laravel 5.2 迁移:无法添加 char 数据类型的外键