sql >> Databáze >  >> RDS >> Mysql

Laravel 5.5 Konsolidujte migrace s produkční databází

Po několika přetechnizovaných a příliš chytrých pokusech o řešení si myslím, že následující je funkční řešení problému.

tl;dr:

  • Migrace na obou stranách migrace, které vytvářejí schéma z ničeho.
  • Aktualizujte projekt.
  • Migrovat.
  • Smažte zarážky a všechny předchozí migrace.
  • Odstraňte záznamy z migrations stůl.

První bookend přejmenuje postižené tabulky. Druhá zarážka zkopíruje data z přejmenovaných tabulek do nových tabulek a poté přejmenované tabulky odstraní.

Poznámka:Uvnitř zarážek na knihy si můžete dělat, co chcete, je to jen minimum.

Řekněme tedy něco jako následující pro migrace:

  • 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

Vytvořili bychom další migraci:

  • 2017_09_05_000004_pre_refresh.php

Vytvořili bychom další migraci na základě znalostí, které nyní máme:

  • 2017_09_05_000005_create_some_table.php

Vytvořili bychom poslední bookend, kde dojde k migraci dat:

  • 2017_09_05_000006_post_refresh.php

První čtyři migrace nebudou spuštěny, protože již byly.

/** 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);
        }
    }
}

Není potřeba down, protože tohle je jednorázový obchod. To se spustí jako první, což by mělo vést k přejmenování všech tabulek uvedených v poli. Poté se spustí konsolidovaná (optimalizovaná) migrace.

/** 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');
        }
    }
}

Po spuštění můžete odstranit všechny své migrace z pre_refresh a předchozí. Stejně jako post_refresh . Poté se můžete vydat do migrations a odstraňte položky pro tyto migrace.

Odstranění položek není úplně nutné, ale pokud migrate:rollback zobrazí se chybové zprávy, že migraci nelze nalézt.

Upozornění

  1. Pokud architektura není svým designem modulární, může být značně těžkopádná. Pokud jste však svůj kód rozdělili do služeb, zdá se to být o něco jednodušší.
  2. Zpracování chyb Laravel a zpráv během migrace jsou velmi omezené; takže ladění může být obtížné.
  3. Důrazně doporučujeme začít s nejstabilnějšími tabulkami ve vaší aplikaci/službě. Dále může být užitečné začít s těmi, které jsou základem vaší aplikace.

Poznámka:Když to skutečně udělám ve výrobě, nejen v místním (znovu a znovu), a pokud neexistuje lepší odpověď, přijmu to.

Úvahy

Pokud svou aplikaci rozdělujete na poskytovatele služeb pomocí diskrétních migrací, můžete poskytovatele služeb komentovat v /config/app když spustíte migraci. Tímto způsobem vytvoříte dávku pro nyní základní službu. Řekněme tedy, že máte následující migrace, kde každé písmeno představuje migraci a každé duplicitní písmeno představuje stejnou službu:

  • A
  • B
  • C
  • A
  • C
  • B
  • A

Po konsolidaci služby A:

  • B
  • C
  • C
  • B
  • A

Po konsolidaci B:

  • C
  • C
  • A
  • B

Po konsolidaci C:

  • A
  • B
  • C

aktualizovat

54 migrací kleslo na 27 zatím. Dokonce jsem vytáhl některé změny schématu z velkého up() a down() a provést z nich samostatné migrace. Příjemným vedlejším účinkem jsou dávky. Provedl jsem migraci počínaje základními tabulkami, na kterých je podporováno vše ostatní; proto je vrácení zpět více službou od služby.



  1. Node.js, Request, MySQL a Connection Pooling vedou k nekonečnému blokování/zmrazování?

  2. codeigniter aktivní záznamy spojit s pomocí?

  3. Přestaňte MySQL tolerovat více hodnot NULL v rámci UNIKÁTNÍHO omezení

  4. Jak vypočítat procento růstu po měsíci v MySQL