将包含外键的列添加到 Laravel 生产中的现有表中
Posted
技术标签:
【中文标题】将包含外键的列添加到 Laravel 生产中的现有表中【英文标题】:Adding column containing foreign key to existing table in production in Laravel 【发布时间】:2021-12-25 02:21:27 【问题描述】:我有一个表participant
,它与表campaign
有many-to-one
关系。现在由于一些愚蠢的原因,我忘记添加一个列campaign_id
,它包含表campaign
中行的外键。现在要解决这个问题,我可以轻松地将以下行添加到 create_participants_table
迁移文件并运行 php artisan migrate:fresh
命令,这将删除所有表并使用正确的列重新创建它们。
$table->unsignedBigInteger('campaign_id');
但问题是这两个表都已经投入生产并且已经包含数据,因此运行migrate:fresh
并不是最佳选择。所以在这种情况下,我会创建另一个名为 add_campaign_id_to_participants
的迁移文件,如下所示:
public function up()
Schema::table('participants', function (Blueprint $table)
$table->unsignedBigInteger('campaign_id');
);
问题是在运行php artisan migrate
时出现错误Cannot add a NOT NULL column with default value NULL
。这似乎是公平的,因为该列不可为空并且没有默认值。但是使列可以为空或设置默认值似乎并不可取。
现在我的participants
表与visitors
表有one-to-one
关系,其中每个参与者都有一个访问者,但不是每个访问者都有一个参与者。同样visitors
表与campaign
表有many-to-one
关系。这意味着理论上我可以为参与者填写刚刚创建的campaign_id
,如下所示:
$participant->visitor->campaign->id
现在我的问题是这是否可行,如果可以,我将如何实现?
【问题讨论】:
尝试`$table->unsignedBigInteger('campaign_id')->nullable();` 或`$table->unsignedBigInteger('campaign_id')->default(0);`。 laravel.com/docs/8.x/migrations#column-modifiers 我认为你没有理解@OlehTytarenko 的问题。 【参考方案1】:我通过将以下内容添加到 add_campaign_id_to_participants
迁移文件来修复它。
public function up()
Schema::table('participants', function (Blueprint $table)
$table->unsignedBigInteger('campaign_id')->default(0);
);
$participants = Participant::all();
foreach($participants as $participant)
$participant->campaign_id = $participant->visitor->campaign_id;
$participant->save();
【讨论】:
您刚刚添加了一个普通列,而不是外键。在外键列中有空值没有错;这只是意味着没有关系。 是的,但就我而言,需要建立关系。每个参与者都需要有一个链接的活动。但是你的意思是我需要使用foreign而不是unsignedBigInteger? 这是业务需求,而不是数据库需求。是的,您需要定义外键或者它只是一个列。 外键不可为空有缺点吗? 不,只是没有必要。您在代码中定义业务规则,例如请求验证以确保关系存在。以上是关于将包含外键的列添加到 Laravel 生产中的现有表中的主要内容,如果未能解决你的问题,请参考以下文章