Mysql
 sql >> база данни >  >> RDS >> Mysql

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

След няколко прекомерно проектирани и прекалено умни опита за решение, мисля, че следното е работещо решение на проблема.

tl;dr:

  • Миграции на Bookend от двете страни на миграцията(ите), които изграждат схемата от нищото.
  • Актуализиране на проекта.
  • Мигриране.
  • Изтрийте подложките за книги и всички предишни миграции.
  • Изтриване на записи от 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 когато стартирате миграциите. По този начин създавате партида за вече базовата услуга. Така че, да приемем, че имате следните миграции, където всяка буква представлява миграция, а всяка дублирана буква представлява една и съща услуга:

  • А
  • Б
  • C
  • А
  • C
  • Б
  • А

След консолидиране на услуга A:

  • Б
  • C
  • C
  • Б
  • А

След консолидиране B:

  • C
  • C
  • А
  • Б

След консолидиране на C:

  • А
  • Б
  • C

актуализация

54 миграции намаляват до 27 досега. Дори извадих някои промени в схемата от голям up() и down() методи и да ги направи отделни миграции. Приятният страничен ефект тук са партидите. Мигрирах, започвайки с базовите таблици, върху които се поддържа всичко останало; следователно връщането назад е повече услуга по услуга.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kubernetes не копира данни в монтиран том

  2. Как да свържа MySQL с Java?

  3. Laravel Eloquent срещу конструктор на заявки - Защо да използвате eloquent за намаляване на производителността

  4. връзка на MATLAB 7.0 и MYSQL

  5. Как да премахнете интервали от низ в MySQL