我正在尝试找出如何处理Laravel 5.2中迁移中的结构性数据以及与数据相关的更改。目前,我只是在对数据库进行结构更改后更改了现有数据。但这似乎与版本控制的代码相冲突。
owner_id
应在teams
表中添加一列。简单迁移,没问题。此后,所有现有团队都应获得此ID。因此,我也将其放入了迁移中:
foreach ($teams as $team) {
// get the first user of this team over a many-to-many-relationship-table `team_user`
$team->owner_id = $team->users->first()->id;
...
}
乍一看效果很好。
经过几天的提交,我决定role
在上述关系表中添加一个数据透视列。我添加了迁移,并在团队模型中输入了以下内容:
public function users() {
return $this->belongsToMany(...)->withPivot('role');
}
如果现在我要完全刷新本地数据库,则在第一次迁移时会出现错误。那是因为它调用了$ team-> users,但是在数据库的这种状态下role
它尚不可用,因此方法调用失败。这就像版本控制和数据库迁移之间的转变。
是否有一个干净的解决方案?
预先感谢,理查德
通常,迁移是DDL(数据定义语言),而种子是DML(数据操作语言)。
迁移数据库表是有序的。您不能添加依赖于某些DDL的代码,这些代码可以在运行那些DDL之前执行。
您还需要考虑的另一件事是:迁移不是进行数据播种,修改和操作的地方,因为播种可能需要在开始播种之前完成所有数据定义。这就是Laravel具有数据种子的原因。
因此,播种,修复或更改数据之间没有区别,全都是DML。您可以在迁移中做到这一点,这不是禁止的,但是在迁移过程中,您必须非常小心,请撤消(关闭)该up
方法中的每个步骤。但是有时候很难操作回您的数据。
您的问题是您试图通过关系访问某些数据,而这些数据尚未准备好(或已完成,或已播种),因为可以执行此操作的迁移尚未运行。因此,DDL和DML之间存在冲突,如果将它们分开对待,则不会发生冲突。
通常,数据播种仅用于测试,但是如果您确实需要,可以在播种器中执行以下操作:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
if (app()->environment('testing')) {
$this->call(TestingSeeders::class);
}
$this->call(ProductionReadySeeders::class);
}
}
或者,您可以仅创建一个用于播种数据的命令:
Artisan::command('app:seed', function ($email)
{
// Do whatever you need to seed your database tables
});
并与
php artisan app:seed
如果要确保每个人都获得了新版本(如果您的应用程序也获得了正确的数据),则可以使用Composer后期执行命令来这样做:
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize",
"php artisan migrate --force",
"php artisan app:seed"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize",
"php artisan migrate --force",
"php artisan app:seed"
]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句