Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Laravel 5.5 Mengonsolidasikan migrasi dengan basis data produksi

Setelah beberapa upaya solusi yang terlalu direkayasa dan terlalu pintar, menurut saya berikut ini adalah solusi yang bisa diterapkan untuk masalah tersebut.

tl; dr:

  • Migrasi akhir buku di kedua sisi migrasi yang membangun skema dari nol.
  • Perbarui proyek.
  • Bermigrasi.
  • Hapus akhir buku dan semua migrasi sebelumnya.
  • Hapus catatan dari migrations meja.

Bookend pertama mengganti nama tabel yang terpengaruh. Bookend kedua menyalin data dari tabel yang diganti namanya ke tabel baru, lalu menghapus tabel yang diganti namanya.

Catatan:Anda dapat melakukan apapun yang Anda suka di dalam buku, ini hanya minimum.

Jadi, katakanlah Anda sesuatu seperti berikut untuk migrasi:

  • 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

Kami akan membuat migrasi lain:

  • 2017_09_05_000004_pre_refresh.php

Kami akan membuat migrasi lain berdasarkan pengetahuan yang kami miliki sekarang:

  • 2017_09_05_000005_create_some_table.php

Kami akan membuat bookend terakhir, di mana migrasi data akan terjadi:

  • 2017_09_05_000006_post_refresh.php

Empat migrasi pertama tidak akan dijalankan karena sudah dijalankan.

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

Tidak perlu turun, karena ini adalah kesepakatan satu tembakan. Ini akan dijalankan terlebih dahulu, yang akan mengakibatkan semua tabel yang terdaftar dalam array diganti namanya. Kemudian migrasi gabungan (dioptimalkan) akan berjalan.

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

Setelah menjalankan ini, Anda dapat menghapus semua migrasi Anda dari pre_refresh dan sebelumnya. Serta post_refresh . Kemudian Anda dapat menuju ke migrations tabel dan hapus entri untuk migrasi tersebut.

Menghapus entri tidak sepenuhnya diperlukan, tetapi jika Anda migrate:rollback Anda akan mendapatkan pesan kesalahan yang menyatakan bahwa migrasi tidak dapat ditemukan.

Peringatan

  1. Jika arsitekturnya tidak dirancang secara modular, itu bisa sangat merepotkan. Namun, jika Anda telah memisahkan kode ke dalam layanan, tampaknya akan sedikit lebih mudah.
  2. Penanganan kesalahan Laravel dan pesan selama migrasi sangat terbatas; jadi, debugging bisa jadi sulit.
  3. Sangat disarankan untuk memulai dengan tabel paling stabil di aplikasi/layanan Anda. Selanjutnya, memulai dengan hal-hal yang mendasar untuk aplikasi Anda mungkin juga terbukti bermanfaat.

Catatan:Ketika saya benar-benar melakukan ini dalam produksi, bukan hanya lokal saya (berulang kali), dan jika tidak ada jawaban yang lebih baik, maka saya akan menerimanya.

Pertimbangan

Jika Anda memecah aplikasi menjadi penyedia layanan dengan migrasi rahasia, Anda dapat mengomentari penyedia layanan di /config/app saat Anda menjalankan migrasi. Dengan cara ini Anda membuat kumpulan untuk layanan yang sekarang menjadi dasar. Jadi, katakanlah Anda memiliki migrasi berikut di mana setiap huruf mewakili migrasi, dan setiap huruf duplikat mewakili layanan yang sama:

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

Setelah mengkonsolidasikan layanan A:

  • B
  • C
  • C
  • B
  • A

Setelah mengkonsolidasikan B:

  • C
  • C
  • A
  • B

Setelah mengkonsolidasikan C:

  • A
  • B
  • C

perbarui

54 migrasi turun menjadi 27 sejauh ini. Saya bahkan mengeluarkan beberapa perubahan Skema dari up() besar dan down() metode dan membuat mereka migrasi terpisah. Efek samping yang bagus di sini adalah batch. Saya bermigrasi mulai dengan tabel dasar yang mendukung segala hal lainnya; oleh karena itu, memutar kembali adalah lebih banyak layanan demi layanan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Masalah penyandian unicode python

  2. Bagaimana cara menulis metode CrudRepository(@Query) khusus untuk memfilter hasil dalam kasus saya

  3. Bagaimana cara memperbarui jika ada, masukkan jika tidak (AKA upsert atau merge) di MySQL?

  4. mysql_fetch_array() mengharapkan parameter 1 menjadi masalah sumber daya

  5. Tambahkan mod_mysql, mod_xml dan mod_zlib ke Apache