Laravel 递归运行 "app/database/migrations" 文件夹中的迁移。

45

因为我有几十个表格,所以我的迁移文件夹看起来像这样,这可以使事情保持组织和清洁:

migrations/
  create_user_table.php
  relations/
  translations/

我想要刷新所有迁移并进行数据填充,但好像遇到了一点小麻烦,我不知道该运行哪个 artisan 命令以递归方式运行迁移(即在 relationstranslations 文件夹中运行迁移)。

我尝试添加 --path="app/database/migrations/*",但它报错了。请问有人知道解决方法吗?


经过搜索,看起来是不可能的:https://github.com/laravel/framework/issues/2561 - tiffanyhwang
不排序/组织迁移的原因是什么?这是一件好事吗? - tiffanyhwang
function rei($folder) { $iterator = new DirectoryIterator($folder); system("php artisan migrate --path=" . $folder); foreach ($iterator as $fileinfo) { if ($fileinfo->isDir() && !$fileinfo->isDot()) { echo $fileinfo->getFilename() . "\n"; rei($folder . $fileinfo->getFilename() . '/'); } } }rei('./database/'); - Carlos Arturo Alaniz
15个回答

64

现在唯一的方法是手动遍历所有迁移。也就是说,您必须在每个子文件夹上运行迁移命令:

php artisan migrate --path=/app/database/migrations/relations  
php artisan migrate --path=/app/database/migrations/translations

然而,您可以轻松地扩展工匠系统以编写自己的迁移命令,该命令将遍历迁移文件夹下的所有文件夹,为您创建这些命令并运行它们。

如果您不想通过Artisan进行操作,也可以简单地编写shell脚本。

编辑:对于Laravel >= 5.0,迁移子目录中的迁移文件的正确命令如下:

php artisan migrate --path=/database/migrations/relations
php artisan migrate --path=/database/migrations/translations


谢谢,最终我选择了脚本路线。 - tiffanyhwang
这对我很有帮助。尽管我对如何使用这种方法进行回滚感到困惑? - Bharat Geleda
1
php artisan migrate:rollback --path=migration/path 相同。 - Oluwatobi Samuel Omisakin
我必须在结尾添加.php才能使其正常工作。 - Black

54

这个加到 AppServiceProvider 中的 boot 方法中。

$mainPath = database_path('migrations');
$directories = glob($mainPath . '/*' , GLOB_ONLYDIR);
$paths = array_merge([$mainPath], $directories);

$this->loadMigrationsFrom($paths);

现在你可以使用 php artisan migrate 命令以及 php artisan migrate:back 命令


5
这是一个非常快速和简单的解决方案。不必再考虑它,也不需要编写不同的bash脚本......只需将您的迁移放在子文件夹中并运行即可。 - Dustin Graham
2
$this 应该是被批准的答案,path 参数只是一个解决方法 :) - dev
2
迁移文件不按顺序连续调用的情况是否可能发生?假设您有 subfolder1/2018-10.phpsubfolder1/2018-12.phpsubfolder2/2018-11.php。那么迁移文件是否仍然会被称为 2018-102018-112018-12 - Adam
2
@Adam - 我刚在 Laravel 5.4 上尝试了一下,它根据文件名对文件进行排序。因此,无论这些文件来自哪个目录,它都会根据文件名(即 2020_07_22_create....)运行它们。 - turtlechief
@turtlechief 是的,我有同样的经历。 - Adam
这实际上应该是 Laravel 的默认部分。 - rockstardev

17

您也可以使用通配符,像这样:

php artisan migrate --path=/database/migrations/*

5
您可以使用以下命令进行递归操作:
php artisan migrate --path=/database/migrations/**/*

**/* 也被称为 globstar

在使用之前,您必须检查您的 bash 是否支持 globstar。 您可以执行 shopt 命令并检查是否存在 globstar 来进行确认。

大多数服务器分发版默认支持 Globstar,但可能无法在 MAC 上运行。

有关 globstar 的更多信息,请参见:https://www.linuxjournal.com/content/globstar-new-bash-globbing-option


测试过了,不起作用。只是出现了一个错误,说找不到路径。 - Michael Ryan Soileau
@MichaelRyanSoileau 我们已经在生产环境中运行了2年,你具体遇到了什么问题?你使用的是哪个系统? - Mazzy
PHP 7.3 运行在 Mac 上,Laravel 版本为 5.5。每次尝试都无效。 :( - Michael Ryan Soileau
啊,好的,我做了一些研究,发现Mac的bash默认不支持globstar(https://apple.stackexchange.com/questions/291287/globstar-invalid-shell-option-name-on-macos-even-with-bash-4-x)。我自己正在运行homestead/vagrant,并在虚拟机中使用终端。但是如果你正在使用你的Mac终端,那么globstar不是本地支持的。我会相应地编辑我的答案。 - Mazzy
啊,一切都解释清楚了。感谢您的尽职调查。 - Michael Ryan Soileau

3
在Laravel 5中,默认情况下,数据库文件夹与应用文件夹并置。所以你可以运行以下命令来迁移单个文件夹的迁移:
php artisan migrate --path=/database/migrations/users

3
你可以尝试使用这个包:nscreed/laravel-migration-paths。默认情况下,migrations文件夹内的所有子目录都会被自动加载。你甚至可以非常容易地添加任何目录。
'paths' => [
    database_path('migrations'),
    'path/to/custom_migrations', // Your Custom Migration Directory
],

不需要任何特殊命令,只需要通用命令:php artisan migrate 即可完成您的任务。


2
这是一个很好的包,我正在我的当前项目中使用它。如果您添加了黑名单功能,那就更好了。虽然我在当前项目中不是非常需要它,但是在研究此功能时,我发现Laravel曾经拒绝过一个功能请求,并且其中一个声明的原因是人们经常使用名为“archive”的子文件夹来存储旧的迁移文件。您可能还想默认屏蔽它。否则,感谢您的出色工作。 - kaan_a
感谢您的建议。 :-) - Mohammad Faisal Islam

1

只有相对路径适用于我(在 Laravel 5.7 中):

php artisan migrate --path=database/migrations/your-folder-with-migrations

1

这适用于 Laravel 8。

执行以下命令:php artisan migrate --path=database/migrations/tenant


1
一个简单的解决方案是创建一个Artisan命令,例如(migrate:all),然后在handle函数内定义每个子目录的迁移命令,如下所述。
Artisan::call('migrate', [
   '--path' => '/database/migrations/employee'
]);

1
我重新编写了MigrationServiceProvider:
- registerResetCommand()
- registerStatusCommand()
- registerMigrateCommand()

在那里,您可以注册自己的命令:

class MigrateCommand extends Illuminate\Database\Console\Migrations\MigrateCommand

之后,您只需要扩展您的目录:
protected function getMigrationPaths()

或者您只需在应用程序启动时注册路径。在了解“$this->loadMigrationsFrom”之前,我已经完成了我的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接