Laravel 5.5 Консолидация миграций с производственной базой данных

Надеюсь, я могу объяснить это хорошо.

У меня есть приложение Laravel, которое находится в производстве уже минуту. Итак, у меня есть куча файлов миграции с множеством изменений. Я хотел бы объединить эти файлы миграции без потери базы данных.

Как я считать это будет работать:

  1. Получите все рабочие таблицы, переведенные в нужное состояние.
  2. Объедините все файлы миграции в минимальное количество необходимых файлов.
  3. Очистить таблицу миграции.
  4. Либо запустите миграцию, либо заполните таблицу миграций.

Отчасти я хотел бы сделать это потому, что я хотел бы сделать общедоступными некоторых поставщиков услуг с максимально чистым набором миграции.

Трудная версия может быть:

  1. Резервное копирование или дублирование таблиц.
  2. Запустите миграции.
  3. Напишите и запустите скрипт для заполнения «чистых» таблиц.

Надеюсь, что есть более простой способ.

Редактировать (из комментариев): У меня есть производственная база данных, которая содержит более 50 файлов миграции — некоторые незначительные изменения, некоторые большие изменения. Если бы я консолидировал, количество необходимых миграций было бы около 12 или около того. Я хотел бы объединить файлы миграции, но все же смогу выполнить migrate:rollback на производстве — не то что бы я.

4

Решение

После нескольких чрезмерно продуманных и слишком умных попыток решения, я думаю, что следующее является реальным решением проблемы.

ТЛ; др:

  • Перспективные миграции по обе стороны от миграций, которые строят схему из ничего.
  • Обновить проект.
  • Перенесите.
  • Удалить форзацы и все предыдущие миграции.
  • Удалить записи из migrations Таблица.

Первый форзац переименовывает затронутые таблицы. Во втором форзаце копируются данные из переименованных таблиц в новые таблицы, а затем удаляются переименованные таблицы.

Примечание: вы можете делать все, что захотите в форзацах, это всего лишь минимум.

Итак, скажем, что-то вроде следующего для миграции:

  • 2017_09_05_000000_create_some_table.php
  • 2017_09_05_000001_add_field_x_to_some_table.php
  • 2017_09_05_000002_add_field_y_to_some_table.php
  • 2017_09_05_000003_add_field_z_to_some_table.php

Мы создали бы другую миграцию:

  • 2017_09_05_000004_pre_refresh.php

Мы создали бы еще одну миграцию, основываясь на знаниях, которые у нас есть сейчас:

  • 2017_09_05_000005_create_some_table.php

Мы создали бы последний форзац, где произойдет миграция данных:

  • 2017_09_05_000006_post_refresh.php

Первые четыре миграции не будут выполнены, потому что они уже были.

/** 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 вы получите сообщения об ошибках, указывающие, что миграция не может быть найдена.

Предостережения

  1. Если архитектура не является модульной по дизайну, она может быть довольно громоздкой. Однако, если вы разделили свой код на сервисы, это выглядит немного проще.
  2. Обработка ошибок Laravel и сообщений во время миграции очень ограничены; Итак, отладка может быть сложной.
  3. Настоятельно рекомендуем начинать с самых стабильных таблиц в вашем приложении / сервисе. Кроме того, начинать с тех, которые являются основополагающими для вашего приложения, также может оказаться полезным.

Примечание: когда я на самом деле делаю это на производстве, а не только на местном (снова и снова), и если нет лучшего ответа, тогда я приму это.

Соображения

Если вы разбиваете свое приложение на поставщиков услуг с осторожной миграцией, то вы можете закомментировать поставщика услуг в /config/app когда вы запускаете миграции. Таким образом, вы создаете пакет для теперь базового сервиса. Итак, допустим, у вас есть следующие миграции, где каждая буква представляет миграцию, а каждая дублирующаяся буква представляет один и тот же сервис:

  • В
  • С
  • С
  • В

После консолидации услуги А:

  • В
  • С
  • С
  • В

После объединения B:

  • С
  • С
  • В

После консолидации C:

  • В
  • С

Обновить

54 миграции до 27 пока. Я даже вытащил некоторые изменения схемы из большого up() а также down() методы и сделать их отдельными миграциями. Хороший побочный эффект здесь — партии. Я мигрировал, начиная с базовых таблиц, на которых поддерживается все остальное; поэтому откат — это больше сервис по сервису.

6

Другие решения

Кажется, вы делаете это неправильно. Обычно вы не должны касаться ваших миграций, поэтому нет смысла объединять их. Особенно, если вы поместили свой код на рабочий сервер, вам вообще не следует его трогать.

Итак, подведем итог: миграция должна помочь вам сохранить схему базы данных в том виде, в каком она должна быть, но если вы захотите поиграть с ними, объединить их или перестроить, вас никто не остановит, но если вы допустите ошибку, вы можете легко что-то сломать.

Нет ничего плохого в том, чтобы выполнять множественные миграции с небольшими изменениями — это то, как это работает, вы вносите изменения в свои файлы PHP, вы вносите изменения в свою схему.

3

Вы могли бы использовать библиотекуxethron/migrations-generator«. Вот Сделки рЕПО.

После установки основное использование:
php artisan migrate:generate

Некоторые обсуждения по этому поводу найдены в Ларакасте.

0
По вопросам рекламы [email protected]