laravel 如何让php artisan:migrate运行一组动态的SQL脚本?

o3imoua4  于 11个月前  发布在  PHP
关注(0)|答案(1)|浏览(120)

我有一个laravel应用程序,它使用的数据库是通过原始SQL脚本迁移的,而不是php迁移。
对于本地开发和测试,我想把这些脚本挂接到php artisan migrate上,我希望每次有人运行php artisan migrate时,laravel会收集这些脚本并运行所有以前没有运行过的脚本。
一种方法是为每个脚本创建一个php迁移文件,但我想知道我是否可以挂钩到收集迁移文件的过程中动态地完成这一点。
我尝试在AppServiceProvider中注册我自己的Migrator示例,但这似乎不起作用。

k10s72fa

k10s72fa1#

  • 首先,创建一个自定义Artisan命令,用于处理原始SQL脚本的执行:
php artisan make:command RunSqlMigrations

字符串

  • 将您的SQL脚本放在特定的目录中,并遵循命名约定,该约定允许您跟踪已执行的SQL脚本,例如在文件名中包含时间戳或版本号。
  • 在数据库中使用一个表来跟踪哪些脚本已经运行。这类似于Laravel的迁移表的工作方式。
  • 在自定义命令中:
<?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()]);
    }
}

  • 在Console/Kernel.php中注册您的新命令,以便它可以作为Artisan命令使用。
  • 你可以通过运行这个命令来使用它:
php artisan migrate:sql

  • 如果要将原始SQL迁移作为php artisan migrate命令的一部分运行,则可以扩展MigrateCommand或侦听MigrationsEnded事件(如果可用),并在正常迁移完成后触发SQL迁移。

PS:我把这些代码从我的老项目。您可以修改它,由于您的需要。

相关问题