Как преобразовать миграции Laravel в необработанные сценарии SQL?
Разработчики из моей команды действительно привыкли к миграции Laravel, они отлично работают на локальных машинах и наших серверах разработчиков. Но администратор базы данных клиента не примет миграцию Laravel. Он запрашивает необработанные сценарии SQL для каждой новой версии нашего приложения.
Существует ли какой-либо инструмент или методика программирования для захвата результатов миграции Laravel в сценарии SQL вверх / вниз?
Было бы идеально, если бы мы могли интегрировать генерацию сценариев SQL в нашу систему CI (TeamCity) при создании производственных сборок.
Кстати, мы будем использовать Laravel 5 и PostgreSQL для этого проекта.
2 ответа
Используйте команду 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
,
На тот случай, если вы столкнулись с той же проблемой, что и я:
php artisan migrate --pretend
ничего не выводил, но запускает SQL без добавления записи в миграцию. Другими словами,
- это делает работу SQL, которая не была предназначена
- ничего не вернул, поэтому я и позвонил
- не добавлял запись в миграции, что разрушает ситуации, так как я не смог перезапустить миграцию без удаления таблиц вручную
Причиной этого была моя настройка с несколькими базами данных, которые адресованы
Schema::connection('master')->create('...
Больше по этому вопросу вы можете найти здесь: https://github.com/laravel/framework/issues/13431
К сожалению, разработчик Laravel закрыл проблему, цитируя фразу "Закрытие, так как проблема, кажется, является редким крайним случаем, который может быть решен с помощью обходного пути.", Поэтому нет большой надежды, что это будет исправлено в ближайшее время. В моем, возможно, редком случае я буду использовать стороннюю проверку различий в SQL.
ура
Код 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'),
];
}
Я использую Laravel 6.X. Для меня ответ @user2479930 не сработал. Мне нужно было прочитать исходный код Migrator и добавить:$migrator->requireFiles($migrations);
чтобы он работал.
$migrator = app('migrator');
$db = $migrator->resolveConnection(null);
$migrations = $migrator->getMigrationFiles('database/migrations');
$migrator->requireFiles($migrations);
$queries = [];
foreach ($migrations as $migration) {
$migration_name = $migration;
$migration = $migrator->resolve($migrator->getMigrationName($migration_name));
$queries[] = [
'name' => $migration_name,
'queries' => array_column($db->pretend(function () use ($migration) {
$migration->up();
}), 'query'),
];
}
dd($queries);
Мне пришлось сделать это после --pretend, измените это:
CreateTablenameTable: create table `tablename` (`id` bigint unsigned not null auto_increment primary key, `code` varchar(255) not null, `valeur` varchar(255) not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci' engine = InnoDB
CreateTablenameTable: alter table `tablename` add unique `tablename_code_unique`(`code`)
К этому:
create table tablename
(
id bigint unsigned not null auto_increment primary key,
code varchar(255) not null,
valeur varchar(255) not null
) default character set utf8mb4 collate 'utf8mb4_unicode_ci' engine = InnoDB;
alter table tablename add unique tablename_code_unique(code);