rake db: skema: memuat vs migrasi

171

Pertanyaan yang sangat sederhana di sini - jika migrasi menjadi lambat dan rumit karena suatu aplikasi menjadi lebih kompleks dan jika kita memiliki lebih banyak pembersih rake db:schema:loaduntuk dipanggil, mengapa migrasi ada sama sekali?

Jika jawaban di atas adalah bahwa migrasi digunakan untuk kontrol versi (catatan bertahap dari perubahan pada database), maka ketika aplikasi menjadi lebih kompleks dan rake db:schema:loaddigunakan lebih banyak, apakah mereka terus mempertahankan fungsi utama mereka?


Peringatan:

Dari jawaban pertanyaan ini: rake db:schema:load akan menghapus data di server produksi jadi hati-hati saat menggunakannya.

sscirrus
sumber
5
+1 Saya tidak pernah mengerti tujuan migrasi; mengapa tidak hanya versi mengendalikan skema?
alternatif
5
@alternative - migrasi memungkinkan Anda melakukan hal-hal lain, seperti jika Anda perlu menambahkan kolom yang bukan nol, Anda dapat dengan cerdas mengisi kolom itu dengan data alih-alih menggunakan beberapa nilai default.
Josh M.

Jawaban:

208

Migrasi memberikan perubahan langkah maju dan mundur ke database. Dalam lingkungan produksi, perubahan tambahan harus dilakukan ke basis data selama penyebaran: migrasi menyediakan fungsionalitas ini dengan rollback failafe aman. Jika Anda menjalankan rake db:schema:loadpada server produksi, Anda akhirnya akan menghapus semua data produksi Anda. Ini adalah kebiasaan yang berbahaya untuk dimasuki.

Yang sedang berkata, saya percaya itu adalah praktik yang layak untuk sesekali "runtuh" ​​migrasi. Ini memerlukan penghapusan migrasi lama, menggantinya dengan migrasi tunggal (sangat mirip dengan schema.rbfile Anda ) dan memperbarui schema_migrationstabel untuk mencerminkan perubahan ini. Berhati-hatilah saat melakukan ini! Anda dapat dengan mudah menghapus data produksi Anda jika Anda tidak hati-hati.

Sebagai catatan, saya sangat percaya bahwa Anda tidak boleh memasukkan pembuatan data dalam file migrasi. The seed.rbfile dapat digunakan untuk ini, atau kebiasaan menyapu atau menyebarkan tugas. Menempatkan ini ke dalam file migrasi mencampur spesifikasi skema database Anda dengan spesifikasi data Anda dan dapat menyebabkan konflik saat menjalankan file migrasi.

jesse reiss
sumber
80
terima kasih telah menginformasikan rake db: schema: load menghapus semua data produksi!
Magne
2
Daripada mengganti migrasi "runtuh" ​​dengan yang baru yang meniru skema, saya menulis permata yang baru saja membersihkannya, dan meminta pengguna untuk menggunakan db:schema:loadjika mereka mencoba untuk db:migratemelawan instalasi baru. @ clear_migrations
Yarin
mungkin jawaban yang jelas tetapi sebelum dorongan pertama untuk produksi, akankah Anda merekomendasikan hanya menghapus semua migrasi dan menggunakan db.schema sebagai migrasi pertama?
dtc
30

Baru saja menemukan posting ini, itu sudah lama sekali dan tidak melihat jawaban yang saya harapkan.

rake db:schema:loadsangat bagus untuk pertama kalinya Anda menempatkan sistem dalam produksi. Setelah itu Anda harus menjalankan migrasi secara normal.

Ini juga membantu Anda membersihkan migrasi Anda kapan pun Anda suka, karena skema memiliki semua informasi untuk membuat mesin lain dalam produksi bahkan ketika Anda membersihkan migrasi Anda.

ereslibre
sumber
Jadi Anda dapat "membersihkan" migrasi Anda karena Anda tidak perlu menggunakannya? Kedengarannya seperti pernyataan aneh.
Abe Petrillo
Tidak jelas bagi saya apa manfaatnya db:schema:loadselain mencukur beberapa detik satu kali sepanjang siklus pengembangan. Pernahkah Anda bekerja dengan aplikasi yang membutuhkan waktu lebih dari 30 detik untuk dibangun? Saat ini saya sedang mengerjakan sebuah aplikasi yang memiliki bug dalam file migrasi itu dan itu tidak akan pernah bermigrasi tanpa memiliki perbaikan bug atau menjalankan db:schema:loadyang membuat saya berpikir skema: memuat adalah ketika ada sesuatu yang salah mengenai pengembangan aplikasi.
Ninjaxor
Argumen lain yang akan saya buat untuk menjaga migrasi adalah bahwa tim inti rail mengarahkan pengguna ke sana instead of editing schema.rb, please use the migrations feature. Jadi, jika Anda menjalankan db:schema:loadfile yang dibuat secara otomatis dan Anda tidak memiliki migrasi untuk membuat-otomatis lagi, Anda secara efektif akan rute "mengedit" skema secara manual dan tidak menggunakan migrasi. Saya berharap saya memiliki kutipan dari panduan rel tentang ini, tetapi mereka tidak membahas skema: memuat, yang menambah rasa frustrasi saya dalam memutuskan bagaimana mendekati skema: memuat fitur. = /
Ninjaxor
Saya datang ke halaman ini tepatnya karena saya setuju dengan itu. Pengalaman saya adalah bahwa begitu situs dalam produksi, jauh lebih aman untuk menggunakan migrasi untuk mengubahnya. Terlepas dari ini, komentar awal db / schema.rb justru menyatakan sebaliknya! (Saya punya masalah di awal setiap proyek karena saya lupa meletakkan db / schema.rb di .gitignore ...)
user1251840
@AbePetrillo wow, saya merindukan komentar ini sepenuhnya. Tentu saja tidak, maksud saya adalah Anda dapat membersihkan migrasi lama yang telah dijalankan pada semua mesin produksi jika Anda mau. Selama bertahun-tahun saya selalu menyimpannya, tetapi pernyataan "membantu Anda membersihkan migrasi kapan pun Anda suka" tidak berarti bahwa "Saya tidak akan pernah harus menggunakan migrasi". Jadi, ketika Anda menggunakan mesin baru, jalankan rake db:schema:loadsebagai lawan rake db:migrate. Kemudian dari sana, Anda bisa rake db:migrate.
ereslibre
9

Migrasi memungkinkan Anda menambahkan data ke db juga. tetapi db: skema: memuat hanya memuat skema.

Shaunak
sumber
6

Karena migrasi dapat dibatalkan, dan menyediakan fungsionalitas tambahan. Misalnya, jika Anda perlu memodifikasi beberapa data sebagai bagian dari perubahan skema maka Anda harus melakukannya sebagai migrasi.

Jamie Penney
sumber
4

Sebagai pengguna ORM lain, bagi saya selalu terasa aneh bahwa Rails tidak memiliki fitur 'sinkronisasi dan pembaruan'. yaitu, dengan menggunakan file skema (yang mewakili keseluruhan, skema terbaru), pergi melalui struktur DB yang ada dan tambahkan / hapus tabel, kolom, indeks sesuai kebutuhan.

Bagi saya ini akan jauh lebih kuat, bahkan jika mungkin sedikit lebih lambat.

Dan James
sumber
1
Tugas untuk memigrasi basis data dengan data dari satu skema rumit ke skema yang lain tidak sepele. Mungkin tidak diselesaikan secara otomatis dan data mungkin tidak dimigrasi secara konsisten dengan satu langkah. Migrasi rel bersifat master dan skema tergantung. Skema secara otomatis dibuat ulang dengan setiap migrasi tetapi tidak sebaliknya.
oklas
Panduan rails sendiri secara eksplisit menyatakan itu schemaadalah master, bukan migrasi.
Drenmi
0

Saya sudah memposting sebagai komentar, tetapi merasa lebih baik meletakkan komentar dari file db / schema.rb di sini:

# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

Sebenarnya, pengalaman saya adalah bahwa lebih baik untuk meletakkan file migrasi di git dan bukan file schema.rb ...

pengguna1251840
sumber
0

rake db:migratemengatur tabel dalam database. Ketika Anda menjalankan perintah migrasi, ia akan mencari di db / migrate / untuk semua file ruby ​​dan menjalankannya dimulai dengan yang tertua. Ada cap waktu di awal setiap nama file migrasi.

Tidak seperti rake db:migrateyang menjalankan migrasi yang belum berjalan, rake db:schema:loadmemuat skema yang sudah dihasilkan db/schema.rbke dalam database.

Anda dapat mengetahui lebih lanjut tentang perintah database rake di sini .

Nesha Zoric
sumber