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

问题描述 投票:0回答:1

我有一个 Laravel 应用程序,它使用的数据库是通过原始 SQL 脚本而不是 php 迁移来迁移的。

对于本地开发和测试,我想将这些脚本挂接到

php artisan migrate
。我期望的行为是每次有人运行
php artisan migrate
时,laravel 都会收集脚本并运行所有之前未运行过的脚本。

执行此操作的一种方法是为每个脚本创建一个 php 迁移文件,但我想知道是否可以连接到收集迁移文件的进程以动态执行此操作。

我尝试在

Migrator
中注册我自己的
AppServiceProvider
实例,但这似乎不起作用。

php sql laravel database-migration
1个回答
0
投票
  • 首先,创建一个自定义 Artisan 命令来处理原始 SQL 脚本的执行:
php artisan make:command RunSqlMigrations
  • 将 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:我从我的旧项目中获取了这些代码。您可以根据您的需要进行修改。

© www.soinside.com 2019 - 2024. All rights reserved.