Haruskah saya menambahkan berkas migrasi Django dalam berkas .gitignore?

130

Haruskah saya menambahkan berkas migrasi Django dalam .gitignoreberkas?

Saya baru-baru ini mendapatkan banyak masalah git karena konflik migrasi dan bertanya-tanya apakah saya harus menandai file migrasi sebagai abaikan.

Jika demikian, bagaimana saya akan menambahkan semua migrasi yang saya miliki di aplikasi saya, dan menambahkannya ke .gitignorefile?

Michael Smith
sumber

Jawaban:

138

Mengutip dari dokumentasi migrasi Django :

File migrasi untuk setiap aplikasi berada dalam direktori "migrasi" di dalam aplikasi itu, dan dirancang untuk digunakan, serta didistribusikan sebagai bagian dari, basis kodenya. Anda harus membuatnya sekali di mesin pengembangan Anda dan kemudian menjalankan migrasi yang sama di mesin rekan Anda, mesin staging Anda, dan akhirnya mesin produksi Anda.

Jika Anda mengikuti proses ini, Anda tidak akan mendapatkan konflik penggabungan apa pun di file migrasi.

Saat menggabungkan cabang kontrol versi, Anda masih mungkin menghadapi situasi di mana Anda memiliki beberapa migrasi berdasarkan migrasi induk yang sama, misalnya jika pengembang yang berbeda memperkenalkan migrasi secara bersamaan. Salah satu cara untuk mengatasi situasi ini adalah dengan memperkenalkan _merge_migration_. Seringkali ini dapat dilakukan secara otomatis dengan perintah

./manage.py makemigrations --merge

yang akan memperkenalkan migrasi baru yang bergantung pada semua migrasi head saat ini. Tentu saja ini hanya berfungsi jika tidak ada konflik antara migrasi head, dalam hal ini Anda harus menyelesaikan masalah secara manual.


Mengingat bahwa beberapa orang di sini menyarankan agar Anda tidak melakukan migrasi ke kontrol versi, saya ingin menjelaskan alasan mengapa Anda sebenarnya harus melakukannya.

Pertama, Anda memerlukan catatan migrasi yang diterapkan ke sistem produksi Anda. Jika Anda menerapkan perubahan pada produksi dan ingin memigrasi database, Anda memerlukan deskripsi tentang status saat ini. Anda dapat membuat cadangan terpisah dari migrasi yang diterapkan ke setiap database produksi, tetapi ini tampaknya tidak praktis.

Kedua, migrasi sering kali berisi kode tulisan tangan kustom. Tidak selalu mungkin untuk membuatnya secara otomatis dengan ./manage.py makemigrations.

Ketiga, migrasi harus dimasukkan dalam tinjauan kode. Itu adalah perubahan yang signifikan pada sistem produksi Anda, dan ada banyak hal yang bisa salah dengannya.

Jadi singkatnya, jika Anda peduli dengan data produksi Anda, periksa migrasi Anda ke kontrol versi.

Sven Marnach
sumber
24
Kami, tim pengembang, juga memiliki masalah yang persis sama. Jika satu anggota tampil makemigrations some_app, tidak hanya model di bawah kendali anggota itu yang akan terpengaruh, tetapi model terkait lainnya juga akan terpengaruh. Artinya, file migrasi (00 * _ *) di aplikasi lain akan diubah. Dan itu menyebabkan banyak masalah konflik selama mendorong atau menarik dari GitHub. Karena saat ini sistem kami belum siap produksi, kami tinggal .gitignorefile migrasi. Kami masih belum tahu bagaimana menyelesaikannya saat sistem berproduksi. Apakah ada yang punya solusi?
Randy Tang
2
Jadi jika saya mengerti dengan baik Anda harus menarik migrasi dari proyek Anda. Ketika Anda mengubah sesuatu, Anda harus melakukan migrasi lokal. Dorong lagi dan buildserver akan melakukan migrasi? (
Tentu
kami tidak pernah menggunakan migrasi django. semua orang terhubung ke database pengujian pusat, jika diperlukan perubahan, itu dilakukan secara manual di tingkat db bila diperlukan. Metode ini berfungsi dengan baik jika sistem cukup matang saat tidak memerlukan banyak pembaruan skema database.
gurel_kaynak
@ yltang52 Saat ini kami sedang mencoba mencari tahu juga, dapatkah Anda berbagi wawasan? Saya pikir setelah Anda pergi ke produksi, Anda tidak punya pilihan selain mempertahankan migrasi tersebut untuk memungkinkan tambalan yang lebih mudah dan kontrol versi yang lebih mudah secara keseluruhan. Saya juga bertanya-tanya apa yang Anda lakukan dengan data keadaan awal (seperti pengaturan yang disimpan dalam db). Bagaimana Anda memeliharanya?
Daniel Dubovski
3
Saya tidak berpikir Anda harus memasukkan file migrasi ke dalam repo. Ini akan merusak status migrasi di lingkungan pengembang orang lain dan lingkungan panggung dan panggung lainnya. (lihat komentar Sugar Tang untuk contoh). File model pelacakan sudah cukup.
Diansheng
19

Anda dapat mengikuti proses di bawah ini.

Anda dapat menjalankan makemigrationssecara lokal dan ini membuat file migrasi. Komit file migrasi baru ini ke repo.

Menurut pendapat saya, Anda tidak boleh menjalankan makemigrationsproduksi sama sekali. Anda dapat menjalankan migrateproduksi dan Anda akan melihat migrasi diterapkan dari file migrasi yang Anda lakukan dari lokal. Dengan cara ini Anda dapat menghindari semua konflik.

DI ENV LOKAL , untuk membuat file migrasi,

python manage.py makemigrations 
python manage.py migrate

Sekarang komit file yang baru dibuat ini, seperti di bawah ini.

git add app/migrations/...
git commit -m 'add migration files' app/migrations/...

DALAM PRODUKSI ENV , jalankan hanya perintah di bawah ini.

python manage.py migrate
SuperNova
sumber
3
Menurut pendapat saya, file migrasi hanya boleh menjadi bagian dari repo setelah aplikasi diterapkan. Itu dihitung sebagai migrasi awal. Jika aplikasi masih dalam pengembangan berat, kami dapat mengabaikannya dengan aman. Tapi begitu itu ditayangkan. Itu dia! Itu tandanya migrasi harus di repo. Setiap anggota lain kemudian perlu mengikuti migrasi ini dan meletakkan milik mereka saat diperlukan
swdev
1
Poin yang sangat bagus untuk hanya menjalankan migratedan TIDAK PERNAH makemigrationsuntuk migrasi yang berkomitmen. Tidak pernah terpikir olehnya.
mempolarisasi
9

Kutipan dari dokumen 2018, Django 2.0. (dua perintah terpisah = makemigrationsdan migrate)

Alasan adanya perintah terpisah untuk membuat dan menerapkan migrasi adalah karena Anda akan melakukan migrasi ke sistem kontrol versi Anda dan mengirimkannya bersama aplikasi Anda; mereka tidak hanya membuat pengembangan Anda lebih mudah, mereka juga dapat digunakan oleh pengembang lain dan dalam produksi.

https://docs.djangoproject.com/en/2.0/intro/tutorial02/

techkuz
sumber
7

TL; DR: lakukan migrasi, selesaikan konflik migrasi, sesuaikan alur kerja git Anda.

Rasanya Anda perlu menyesuaikan alur kerja git Anda , daripada mengabaikan konflik.

Idealnya, setiap fitur baru dikembangkan di cabang yang berbeda, dan digabungkan kembali dengan permintaan penarikan .

PR tidak dapat digabungkan jika ada konflik, oleh karena itu siapa yang perlu menggabungkan fiturnya perlu menyelesaikan konflik, termasuk migrasi. Ini mungkin membutuhkan koordinasi antara tim yang berbeda.

Penting juga untuk melakukan file migrasi! Jika konflik muncul, Django bahkan mungkin membantu Anda menyelesaikan konflik tersebut ;)

Sdra
sumber
Itu jawaban yang benar. Alur kerja sistem versi operasional tampaknya tersirat dalam dokumentasi django tetapi fundamental.
Eric
3

Saya tidak dapat membayangkan mengapa Anda akan mendapatkan konflik, kecuali Anda mengedit migrasi entah bagaimana caranya? Itu biasanya berakhir buruk - jika seseorang melewatkan beberapa komitmen perantara maka mereka tidak akan meningkatkan dari versi yang benar, dan salinan database mereka akan rusak.

Proses yang saya ikuti cukup sederhana - setiap kali Anda mengubah model untuk suatu aplikasi, Anda juga melakukan migrasi, dan kemudian migrasi itu tidak berubah - jika Anda memerlukan sesuatu yang berbeda dalam model, maka Anda mengubah model dan melakukan migrasi baru bersama perubahan Anda.

Dalam proyek greenfield, Anda sering dapat menghapus migrasi dan memulai kembali dari awal dengan migrasi 0001_ ketika Anda merilis, tetapi jika Anda memiliki kode produksi, Anda tidak bisa (meskipun Anda dapat menekan migrasi menjadi satu).

Anthony Briggs
sumber
Poin bagus tentang memulai kembali dari awal dengan 0001 untuk rilis.
andho
3

Solusi yang biasanya digunakan adalah, sebelum apa pun digabungkan menjadi master, pengembang harus melakukan perubahan jarak jauh. Jika ada konflik dalam versi migrasi, dia harus mengganti nama migrasi lokalnya (migrasi jarak jauh telah dijalankan oleh pengembang lain, dan, berpotensi, dalam produksi), menjadi N + 1.

Selama pengembangan mungkin baik-baik saja untuk tidak melakukan migrasi (jangan tambahkan abaikan, jangan lakukan additu). Tetapi setelah Anda masuk ke produksi, Anda akan membutuhkannya untuk menjaga skema tetap sinkron dengan perubahan model.

Anda kemudian perlu mengedit file, dan mengubah dependencieske versi jarak jauh terbaru.

Ini bekerja untuk migrasi Django, serta aplikasi serupa lainnya (sqlalchemy + alembic, RoR, dll).

WhyNotHugo
sumber
1

Memiliki banyak file migrasi di git itu berantakan. Hanya ada satu file di folder migrasi yang tidak boleh Anda abaikan. File tersebut adalah file init .py, Jika Anda mengabaikannya, python tidak akan lagi mencari submodul di dalam direktori, jadi setiap upaya untuk mengimpor modul akan gagal. Jadi pertanyaannya adalah bagaimana cara mengabaikan semua file migrasi kecuali init .py? Solusinya adalah: Tambahkan '0 * .py' ke file .gitignore dan itu melakukan pekerjaan dengan sempurna.

Semoga ini bisa membantu seseorang.

Gizachew Soboksa
sumber
1

Abaikan migrasi, jika Anda memiliki DB terpisah untuk lingkungan Pengembangan, Pementasan dan Produksi. Untuk dev. tujuan Anda dapat menggunakan DB sqlite lokal dan bermain dengan migrasi secara lokal. Saya akan merekomendasikan Anda untuk membuat empat cabang tambahan:

  1. Master - Bersihkan kode baru tanpa migrasi. Tidak ada yang terhubung ke cabang ini. Digunakan untuk review kode saja

  2. Pembangunan - perkembangan sehari-hari. Dorong / tarik diterima. Setiap pengembang sedang mengerjakan sqlite DB

  3. Cloud_DEV_env - lingkungan DEV cloud / server jarak jauh. Tarik saja. Pertahankan migrasi secara lokal di mesin, yang digunakan untuk penerapan kode dan migrasi jarak jauh database Dev

  4. Cloud_STAG_env - lingkungan STAG cloud / server jarak jauh. Tarik saja. Simpan migrasi secara lokal di mesin, yang digunakan untuk penerapan kode dan migrasi jarak jauh database Stag

  5. Cloud_PROD_env - lingkungan DEV cloud / server jarak jauh. Tarik saja. Pertahankan migrasi secara lokal di mesin, yang digunakan untuk penerapan kode dan migrasi jarak jauh database Prod

Catatan: 2, 3, 4 - migrasi dapat disimpan dalam repo tetapi harus ada aturan ketat penggabungan permintaan tarik, jadi kami memutuskan untuk mencari seseorang, yang bertanggung jawab atas penerapan, jadi satu-satunya orang yang memiliki semua file migrasi - penerapan kami -er. Dia menyimpan migrasi DB jarak jauh setiap kali ada perubahan dalam Model.

Yevhen Dyachenko
sumber
-3

Jawaban singkat yang saya usulkan tidak termasuk migrasi di repo. Setelah kode digabungkan, jalankan saja ./manage.py makemigrationsdan Anda siap.

Jawaban panjang Saya tidak berpikir Anda harus memasukkan file migrasi ke dalam repo. Ini akan merusak status migrasi di lingkungan pengembang orang lain dan lingkungan panggung dan panggung lainnya. (lihat komentar Sugar Tang untuk contoh).

Dalam sudut pandang saya, tujuan migrasi Django adalah untuk menemukan celah antara status model sebelumnya dan status model baru, dan kemudian serialisasi kesenjangan. Jika model Anda berubah setelah penggabungan kode, Anda dapat melakukannya dengan mudah makemigrationsuntuk mengetahui celahnya. Mengapa Anda ingin menggabungkan migrasi lain secara manual dan hati-hati ketika Anda dapat mencapai yang sama secara otomatis dan bebas bug? Dokumentasi Django mengatakan,

Mereka * (migrasi) * dirancang untuk sebagian besar otomatis

; tolong tetap seperti itu. Untuk menggabungkan migrasi secara manual, Anda harus memahami sepenuhnya apa yang telah diubah oleh orang lain dan ketergantungan apa pun dari perubahan tersebut. Itu banyak overhead dan rawan kesalahan. Jadi file model pelacakan sudah cukup.

Ini adalah topik yang bagus di alur kerja. Saya terbuka untuk opsi lain.

Diansheng
sumber
4
Ini hanya akan berhasil untuk proyek mainan, dan memiliki banyak kelemahan. Ini segera berhenti bekerja untuk migrasi tulisan tangan, untuk layanan yang menggunakan beberapa server aplikasi singkat (yaitu aplikasi serius apa pun ) dan untuk aplikasi yang terdiri dari banyak aplikasi Django masing-masing dengan migrasinya sendiri. Dan saya tidak mengerti apa yang Anda maksud dengan "menggabungkan migrasi secara manual" - manage.py makemigrations --mergebekerja sepenuhnya secara otomatis untuk saya.
Sven Marnach
@ Sven Marnach, saya memang mengerjakan aplikasi kecil tapi serius. Dan itu berhasil untuk saya.
Diansheng