Подтвердить что ты не робот

Как конвертировать Laravel в сырые SQL-скрипты?

Разработчики моей команды действительно привыкли к возможностям миграции Laravel, они отлично работают на локальных машинах и наших dev-серверах. Но администратор базы данных клиентов не будет принимать миграцию Laravel. Он запрашивает необработанные SQL-скрипты для каждой новой версии нашего приложения.

Есть ли какой-либо инструмент или метод программирования для вывода результатов миграции Laravel в SQL-скрипты вверх/вниз?

Было бы идеально, если бы мы могли интегрировать генерации SQL script в нашу систему CI (TeamCity) при создании производственных сборок.

Кстати, мы будем использовать Laravel 5 и PostgreSQL для этого проекта.

4b9b3361

Ответ 1

Используйте команду 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")"
    ]
  ]
]

Этот код будет включать в себя все миграции. Чтобы узнать, как получить только то, что еще не перенесено, посмотрите на метод run() в vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php.

Ответ 2

На тот случай, если вы столкнулись с той же проблемой, что и я:

php artisan migrate --pretend

ничего не выводил, но запускает SQL без добавления записи в миграцию. Другими словами,

  • это делает работу SQL, которая не была предназначена
  • ничего не вернул, поэтому я и позвонил
  • не добавлял запись в миграции, что разрушает ситуации, так как я не смог перезапустить миграцию без удаления таблиц вручную

Причиной этого была моя настройка с несколькими базами данных, которые адресованы

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

Больше по этому вопросу вы можете найти здесь: https://github.com/laravel/framework/issues/13431

К сожалению, разработчик Laravel закрыл проблему, цитируя фразу "Закрытие, так как проблема, кажется, является редким крайним случаем, который может быть решен с помощью обходного пути.", Поэтому нет большой надежды, что это будет исправлено в ближайшее время. В моем, возможно, редком случае я буду использовать стороннюю проверку различий в SQL.

ура

Ответ 3

Код 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'),
        ];
    }