我有一个 Laravel 应用程序,它使用的数据库是通过原始 SQL 脚本而不是 php 迁移来迁移的。
对于本地开发和测试,我想将这些脚本挂接到
php artisan migrate
。我期望的行为是每次有人运行 php artisan migrate
时,laravel 都会收集脚本并运行所有之前未运行过的脚本。
执行此操作的一种方法是为每个脚本创建一个 php 迁移文件,但我想知道是否可以连接到收集迁移文件的进程以动态执行此操作。
我尝试在
Migrator
中注册我自己的 AppServiceProvider
实例,但这似乎不起作用。
php artisan make:command RunSqlMigrations
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class RunSqlMigrations extends Command
{
protected $signature = 'migrate:sql';
protected $description = 'Run raw SQL migrations';
public function handle()
{
$sqlDirectory = database_path('sql_migrations');
$files = File::allFiles($sqlDirectory);
foreach ($files as $file) {
$filename = $file->getFilename();
if ($this->alreadyRun($filename)) {
$this->info("Skipping: {$filename}");
continue;
}
try {
DB::unprepared(File::get($file->getPathname()));
$this->recordAsRun($filename);
$this->info("Migrated: {$filename}");
} catch (\Exception $e) {
$this->error("Failed to migrate: {$filename}");
return;
}
}
}
protected function alreadyRun($filename)
{
return DB::table('sql_migrations')->where('filename', $filename)->exists();
}
protected function recordAsRun($filename)
{
DB::table('sql_migrations')->insert(['filename' => $filename, 'migrated_at' => now()]);
}
}
php artisan migrate:sql
php artisan migrate
命令的一部分运行,您可以扩展 MigrateCommand
或侦听 MigrationsEnded
事件(如果可用),并在正常迁移完成后触发 SQL 迁移。 PS:我从我的旧项目中获取了这些代码。您可以根据您的需要进行修改。