Saya telah membuat migrasi yang menambahkan tabel baru dan ingin mengembalikannya dan menghapus migrasi, tanpa membuat migrasi baru.
Bagaimana saya melakukannya? Apakah ada perintah untuk mengembalikan migrasi terakhir dan kemudian saya bisa menghapus file migrasi?
django
django-migrations
Ronen Ness
sumber
sumber
migrate
perintah membiarkan kau menggunakan./manage.py migrate my_app zero
untuk unapply semua migrasi untuk aplikasi.'0010_previous_migration'
, saya tidak tahu mengapa Anda akan melihat perilaku itu.Jawaban oleh Alasdair mencakup dasar-dasarnya
./manage.py showmigrations
migrate
menggunakan nama aplikasi dan nama migrasiTetapi harus ditunjukkan bahwa tidak semua migrasi dapat dibatalkan. Ini terjadi jika Django tidak memiliki aturan untuk melakukan pembalikan. Untuk sebagian besar perubahan yang Anda lakukan migrasi secara otomatis
./manage.py makemigrations
, pembalikan akan dimungkinkan. Namun, skrip khusus harus memiliki maju dan mundur ditulis, seperti yang dijelaskan dalam contoh di sini:https://docs.djangoproject.com/en/1.9/ref/migration-operations/
Cara melakukan pembalikan no-op
Jika Anda memiliki
RunPython
operasi, maka mungkin Anda hanya ingin mundur migrasi tanpa menulis skrip pembalikan yang ketat secara logis. Retas cepat berikut untuk contoh dari dokumen (tautan di atas) memungkinkan ini, meninggalkan database dalam keadaan yang sama setelah migrasi diterapkan, bahkan setelah membalikkannya.Ini berfungsi untuk Django 1.8, 1.9
Update: Cara yang lebih baik dari menulis ini akan menggantikan
lambda apps, schema_editor: None
denganmigrations.RunPython.noop
di potongan di atas. Secara fungsional keduanya adalah hal yang sama. (kredit untuk komentar)sumber
RunPython.noop
bukannya lambda inline atau equivelentmigrations.RunPython(forwards_func, migrations.RunPython.noop)
. Perlu memeriksa itu secara fungsional. Itu harus ditambahkan sebagai jawaban atau edit untuk yang satu ini suatu saat.Inilah solusi saya, karena solusi di atas tidak benar-benar mencakup kasus penggunaan, ketika Anda menggunakannya
RunPython
.Anda dapat mengakses tabel melalui ORM dengan
Jadi, Anda dapat meminta tabel dan menghapus entri yang relevan untuk Anda. Dengan cara ini Anda dapat memodifikasi secara detail. Dengan
RynPython
migrasi Anda juga harus menjaga data yang ditambahkan / diubah / dihapus. Contoh di atas hanya menampilkan, bagaimana Anda mengakses tabel melalui Djang ORM.sumber
django.db.utils.ProgrammingError: relation "<relation name>" already exists
saya membuatmigrate --fake
yang salah, jadi saya mencoba untuk kembali, lalu sayapsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
Hal lain yang dapat Anda lakukan adalah menghapus tabel yang dibuat secara manual.
Bersamaan dengan itu, Anda harus menghapus file migrasi tertentu. Juga, Anda harus menghapus entri tertentu itu di tabel migrasi-Django (mungkin yang terakhir dalam kasus Anda) yang berkorelasi dengan migrasi tertentu.
sumber
Jangan hapus file migrasi sampai setelah pengembalian. Saya membuat kesalahan ini dan tanpa file migrasi, database tidak tahu apa yang harus dihapus.
Hapus file migrasi. Setelah migrasi yang diinginkan ada di model Anda ...
sumber
Saya melakukan ini di 1.9.1 (untuk menghapus migrasi terakhir atau terbaru yang dibuat):
rm <appname>/migrations/<migration #>*
contoh:
rm myapp/migrations/0011*
masuk ke database dan menjalankan SQL ini (postgres dalam contoh ini)
delete from django_migrations where name like '0011%';
Saya kemudian dapat membuat migrasi baru yang dimulai dengan nomor migrasi yang baru saja saya hapus (dalam hal ini, 11).
sumber
Jawaban ini untuk kasus serupa jika jawaban teratas oleh Alasdair tidak membantu . (Misalnya jika migrasi yang tidak diinginkan segera dibuat lagi dengan setiap migrasi baru atau jika itu dalam migrasi yang lebih besar yang tidak dapat dikembalikan atau tabel telah dihapus secara manual.)
TL; DR : Anda dapat menghapus beberapa migrasi yang terakhir dikembalikan (bingung) dan membuat yang baru setelah memperbaiki model . Anda juga dapat menggunakan metode lain untuk mengonfigurasinya agar tidak membuat tabel dengan perintah migrasi. Migrasi terakhir harus dibuat agar sesuai dengan model saat ini .
Kasus mengapa ada orang yang tidak ingin membuat tabel untuk Model yang harus ada:
A) Tidak ada tabel seperti itu harus ada di tidak ada database di mesin tidak dan tidak ada kondisi
class Meta: abstract = True
B) Tabel jarang dibuat, oleh sesuatu yang lain atau secara manual dengan cara khusus.
class Meta: managed = False
Migrasi dibuat, tetapi tidak pernah digunakan, hanya dalam tes. File migrasi penting, jika tidak, tes database tidak dapat berjalan, mulai dari keadaan awal yang dapat direproduksi.
C) Tabel ini hanya digunakan pada beberapa mesin (misalnya dalam pengembangan).
class Meta: managed = some_switch
.D) Proyek ini menggunakan banyak basis data di
settings.DATABASES
allow_migrate
untuk membedakan database di mana tabel harus dibuat dan di mana tidak.Migrasi dibuat dalam semua kasus A), B), C), D) dengan Django 1.9+ (dan hanya dalam kasus B, C, D dengan Django 1.8), tetapi diterapkan ke database hanya dalam kasus yang sesuai atau mungkin tidak pernah jika diperlukan begitu. Migrasi diperlukan untuk menjalankan tes sejak Django 1.8. Keadaan saat ini yang relevan lengkap dicatat oleh migrasi bahkan untuk model dengan managed = False di Django 1.9+ agar dimungkinkan untuk membuat ForeignKey antara model yang dikelola / tidak dikelola atau untuk dapat membuat model dikelola = Benar nanti. (Pertanyaan ini telah ditulis pada saat Django 1.8. Semuanya di sini harus valid untuk versi antara 1,8 hingga saat ini 2.2.)
Jika migrasi terakhir tidak mudah dikembalikan maka dimungkinkan untuk berhati-hati (setelah cadangan basis data) melakukan pengembalian palsu
./manage.py migrate --fake my_app 0010_previous_migration
, hapus tabel secara manual.Jika perlu, buat migrasi tetap dari model tetap dan terapkan tanpa mengubah struktur basis data
./manage.py migrate --fake my_app 0011_fixed_migration
.sumber
Jika Anda menghadapi masalah saat mengembalikan migrasi, dan entah bagaimana telah mengacaukannya, Anda dapat melakukan
fake
migrasi.Untuk versi Django <1,7 ini akan membuat entri dalam
south_migrationhistory
tabel, Anda perlu menghapus entri itu.Sekarang Anda dapat mengembalikan migrasi dengan mudah.
PS: Saya macet selama banyak waktu dan melakukan migrasi palsu dan kemudian kembali membantu saya.
sumber