web-dev-qa-db-ja.com

変換方法Laravel=生のSQLスクリプトへの移行?

私のチームの開発者はLaravel移行のパワーに本当に慣れており、ローカルマシンと開発サーバーでうまく機能しています。ただし、顧客のデータベース管理者はLaravel移行を受け入れません。彼は、アプリケーションの新しいバージョンごとに生のSQLスクリプトを要求します。

アップ/ダウンSQLスクリプトへのLaravel移行からの出力をキャプチャするツールまたはプログラミング手法はありますか?

実稼働ビルドの作成時に、CIシステム(TeamCity)にSQLスクリプト生成を統合できれば完璧です。

ところで、このプロジェクトではLaravel 5とPostgreSQLを使用します。

32
JustAMartin

Migrateコマンドを使用する

_--pretend_を実行して端末にクエリを出力するときに、_php artisan migrate_フラグを追加できます。

_php artisan migrate --pretend
_

これは次のようになります。

_Migration table created successfully.
CreateUsersTable: create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)
CreateUsersTable: create unique index users_email_unique on "users" ("email")
CreatePasswordResetsTable: create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)
CreatePasswordResetsTable: create index password_resets_email_index on "password_resets" ("email")
CreatePasswordResetsTable: create index password_resets_token_index on "password_resets" ("token")
_

これをファイルに保存するには、出力をリダイレクトしますansiなし

_php artisan migrate --pretend --no-ansi > migrate.sql
_

このコマンドには、まだ移行されていない移行のみが含まれます。


移行コマンドをハックする

クエリの取得方法をさらにカスタマイズするには、ソースをハッキングして独自のカスタムコマンドなどを作成することを検討してください。始める前に、すべての移行を取得する簡単なコードを次に示します。

サンプルコード

_$migrator = app('migrator');
$db = $migrator->resolveConnection(null);
$migrations = $migrator->getMigrationFiles('database/migrations');
$queries = [];

foreach($migrations as $migration) {
    $migration_name = $migration;
    $migration = $migrator->resolve($migration);

    $queries[] = [
        'name' => $migration_name,
        'queries' => array_column($db->pretend(function() use ($migration) { $migration->up(); }), 'query'),
    ];
}

dd($queries);
_

出力例

_array:2 [
  0 => array:2 [
    "name" => "2014_10_12_000000_create_users_table"
    "queries" => array:2 [
      0 => "create table "users" ("id" integer not null primary key autoincrement, "name" varchar not null, "email" varchar not null, "password" varchar not null, "remember_token" varchar null, "created_at" datetime not null, "updated_at" datetime not null)"
      1 => "create unique index users_email_unique on "users" ("email")"
    ]
  ]
  1 => array:2 [
    "name" => "2014_10_12_100000_create_password_resets_table"
    "queries" => array:3 [
      0 => "create table "password_resets" ("email" varchar not null, "token" varchar not null, "created_at" datetime not null)"
      1 => "create index password_resets_email_index on "password_resets" ("email")"
      2 => "create index password_resets_token_index on "password_resets" ("token")"
    ]
  ]
]
_

このコードにはall移行が含まれます。まだ移行されていないもののみを取得する方法については、_vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php_のrun()メソッドをご覧ください。

74
user2479930

あなたが私と同じ問題に直面している場合に備えて:

_php artisan migrate --pretend_

何も出力しませんでしたが、移行にレコードを追加せずにSQLを実行します。言い換えると、

  • 意図しないSQLジョブを実行します
  • 何も返さなかったので、電話をかけたのは
  • エントリを移行に追加しなかったため、手動でテーブルを削除しないと移行を再実行できなかったため、状況が破壊されます

その理由は、いくつかのデータベースを使用してセットアップしたためです。

Schema::connection('master')->create('...

この問題の詳細については、こちらをご覧ください: https://github.com/laravel/framework/issues/13431

悲しいことに、Laravel開発者は問題をクローズしました、引用符 "問題は回避策で解決できるまれなEdgeのケースだと思われるため、クローズします。"私の多分まれなケースでは、サードパーティのSQL diffチェッカーを使用します。

乾杯

1
andi79h

user2479930のコードは素晴らしいですが、私は得ていました:

Class 'LocalItemsSchema.php' not found

問題をデバッグし、次のように修正しました。

foreach($migrations as $migration) {
        $migration_name = $migration;
        $migration_name = str_replace('.php', '', $migration_name);
        $migration = $migrator->resolve($migration_name);

        $queries[] = [
            'name' => $migration_name,
            'queries' => array_column($db->pretend(function() use ($migration) { $migration->up(); }), 'query'),
        ];
    }
1
Eugene Gekhter