Надеюсь, я могу объяснить это хорошо.
У меня есть приложение Laravel, которое находится в производстве уже минуту. Итак, у меня есть куча файлов миграции с множеством изменений. Я хотел бы объединить эти файлы миграции без потери базы данных.
Как я считать это будет работать:
Отчасти я хотел бы сделать это потому, что я хотел бы сделать общедоступными некоторых поставщиков услуг с максимально чистым набором миграции.
Трудная версия может быть:
Надеюсь, что есть более простой способ.
Редактировать (из комментариев): У меня есть производственная база данных, которая содержит более 50 файлов миграции — некоторые незначительные изменения, некоторые большие изменения. Если бы я консолидировал, количество необходимых миграций было бы около 12 или около того. Я хотел бы объединить файлы миграции, но все же смогу выполнить migrate:rollback
на производстве — не то что бы я.
После нескольких чрезмерно продуманных и слишком умных попыток решения, я думаю, что следующее является реальным решением проблемы.
ТЛ; др:
migrations
Таблица. Первый форзац переименовывает затронутые таблицы. Во втором форзаце копируются данные из переименованных таблиц в новые таблицы, а затем удаляются переименованные таблицы.
Примечание: вы можете делать все, что захотите в форзацах, это всего лишь минимум.
Итак, скажем, что-то вроде следующего для миграции:
Мы создали бы другую миграцию:
Мы создали бы еще одну миграцию, основываясь на знаниях, которые у нас есть сейчас:
Мы создали бы последний форзац, где произойдет миграция данных:
Первые четыре миграции не будут выполнены, потому что они уже были.
/** 2017_09_05_000004_pre_refresh.php */
class PreRefresh extends Migration
{
public function up()
{
$prefix = 'zz_';
$tablesToRename = [
'foos',
'bars'
];
foreach($tablesToRename as $table) {
Schema::rename($table, $prefix . $table);
}
}
}
Нет необходимости в падении, потому что это сделка с одним выстрелом. Сначала он запустится, что должно привести к переименованию всех таблиц, перечисленных в массиве. Затем будет выполнена консолидированная (оптимизированная) миграция (и).
/** 2017_09_05_000006_post_refresh.php */
class PostRefresh extends Migration
{
public function up()
{
// Do what you need to do.
// If you cannot use your models, just use DB::table() commands.
$foos = DB::table('zz_foos')->get();
foreach ($foos as $foo) {
DB::table('foo')->insert([
'id' => $foo->id,
'created_at' => $foo->created_at,
'updated_at' => $foo->updated_at
]);
}
$bars = DB::table('zz_bars')->get();
foreach ($bars as $bar) {
DB::table('bar')->insert([
'id' => $bar->id,
'created_at' => $bar->created_at,
'updated_at' => $bar->updated_at,
'foo_id' => $bar->foo_id
]);
}
// Tear down.
$prefix = 'zz_';
$tablesToRename = [
'foo',
'bar'
];
foreach ($tablesToRename as $table) {
DB::statement('SET FOREIGN_KEY_CHECKS=0');
Schema::dropIfExists($prefix . $table);
DB::statement('SET FOREIGN_KEY_CHECKS=1');
}
}
}
После этого вы можете удалить все ваши миграции из pre_refresh
и до. Так же хорошо как post_refresh
, Тогда вы можете отправиться в migrations
таблицу и удалите записи для этих миграций.
Удаление записей не является полностью необходимым, но если вы migrate:rollback
вы получите сообщения об ошибках, указывающие, что миграция не может быть найдена.
Примечание: когда я на самом деле делаю это на производстве, а не только на местном (снова и снова), и если нет лучшего ответа, тогда я приму это.
Если вы разбиваете свое приложение на поставщиков услуг с осторожной миграцией, то вы можете закомментировать поставщика услуг в /config/app
когда вы запускаете миграции. Таким образом, вы создаете пакет для теперь базового сервиса. Итак, допустим, у вас есть следующие миграции, где каждая буква представляет миграцию, а каждая дублирующаяся буква представляет один и тот же сервис:
После консолидации услуги А:
После объединения B:
После консолидации C:
Обновить
54 миграции до 27 пока. Я даже вытащил некоторые изменения схемы из большого up()
а также down()
методы и сделать их отдельными миграциями. Хороший побочный эффект здесь — партии. Я мигрировал, начиная с базовых таблиц, на которых поддерживается все остальное; поэтому откат — это больше сервис по сервису.
Кажется, вы делаете это неправильно. Обычно вы не должны касаться ваших миграций, поэтому нет смысла объединять их. Особенно, если вы поместили свой код на рабочий сервер, вам вообще не следует его трогать.
Итак, подведем итог: миграция должна помочь вам сохранить схему базы данных в том виде, в каком она должна быть, но если вы захотите поиграть с ними, объединить их или перестроить, вас никто не остановит, но если вы допустите ошибку, вы можете легко что-то сломать.
Нет ничего плохого в том, чтобы выполнять множественные миграции с небольшими изменениями — это то, как это работает, вы вносите изменения в свои файлы PHP, вы вносите изменения в свою схему.
Вы могли бы использовать библиотекуxethron/migrations-generator
«. Вот Сделки рЕПО.
После установки основное использование:
php artisan migrate:generate
Некоторые обсуждения по этому поводу найдены в Ларакасте.