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

How to properly handle database data changes with laravel migrations and seeds

我有我的迁移文件,它为数据库创建初始模式,我有我的种子文件,它使用随机数据和设置类型填充初始模式。

我对迁移和种子的理解是,无论何时有新的团队成员加入,他都可以 运行 他们并跟上所有数据库的变化和产品工作所需的数据,另外,您可以通过 运行ning 迁移文件将更改应用到 stg 和 prod。

但是,随着我的项目的推进,新类型的数据不断涌现,应用它们的唯一方法是创建一个将 运行 插入到数据库中的迁移。

我遇到的问题是 artisan 使用迁移和种子的方式是它首先 运行 所有迁移,然后 运行 所有种子,而且我似乎没有办法指定它们应该 运行 的顺序。因此,如果我 运行 a migrate:refresh --seed 我会遇到错误,因为它应用了最新的迁移,它插入了新数据(可能会或可能不会,取决于types inserted in the seeds) 在种子插入他自己的数据之前。

我们尝试的一个解决方案是也更新种子,并在应用插入数据的迁移更改之前进行检查,但这已经变得非常难以维护。

对于这种情况,迁移和种子的预期用途是什么?

更新 为了使它更清楚: 假设我有一个创建用户的迁移: 用户:{id, name, type} 我有我的种子来创建用户。

我 运行 都有,我有一个用户 table 和一堆用户。

时间流逝,我们决定 user_types 需要一个 table。 创建一个迁移,它将创建新的 table,并填充新用户类型和更新的数据以匹配当前的 user.type 到 user.type_id。

开发人员 运行 进行迁移,他们的数据库都是最新的。

一个新的开发者加入了团队。他 运行 负责迁移。然后是种子。 坏了。

现在,如果我们更新种子以匹配最新的,我们将 运行 变成 user_types table 的重复数据。为避免这种情况,我们需要在迁移过程中使用某种防御性代码,以便在没有数据时不 运行 事物,并在有数据时进行更新。

问题是,这是使用迁移的正确方法吗?如何将数据更改推送给所有开发人员,而无需重新 运行 种子?

我认为迁移不应该依赖于种子中的任何数据。种子应该期待最新的迁移模式。因此,每当您的模式发生变化时,您应该相应地更新种子并执行 migrate:fresh --seed。至少,这就是我正在做的。

由于您已经这样做了,我想知道是什么让您成为 "troublesome process"。能详细点吗?

看了你的解释,我好像明白了。

您的播种者应该做的第一件事是删除所有内容,这样您始终从一个空数据库开始,至少在播种者应该关注的地方。

我还会仔细查看文档 https://laravel.com/docs/5.2/seeding,特别是 "Using Model Factories".

部分
public function run()
{
    factory(App\User::class, 50)->create()->each(function($u) {
        $u->posts()->save(factory(App\Post::class)->make());
    });
}

在这种情况下,您将执行类似的操作,只是您将从顶部开始,对您来说是 user_types,然后对于它创建的每种类型,它会生成您需要的任意数量的用户。这似乎与您当前的流程有点不同,听起来您每个 table.

都有一个种子文件

这样,您就可以处理 parent/child 关系,并在代码中将其表达得非常清楚,以后添加其他项目也很容易。此外,由于每次播种器 运行 基本上都是从头开始,因此您可以确定这对新开发者和现有开发者都适用。