Saya memiliki aplikasi Django dengan empat model di dalamnya. Saya menyadari sekarang bahwa salah satu model ini harus di aplikasi yang terpisah. Saya memang telah menginstal selatan untuk migrasi, tetapi saya tidak berpikir ini adalah sesuatu yang dapat ditangani secara otomatis. Bagaimana saya bisa memigrasi salah satu model dari aplikasi lama ke yang baru?
Juga, perlu diingat bahwa saya akan membutuhkan ini untuk menjadi proses yang berulang, sehingga saya dapat memigrasi sistem produksi dan semacamnya.
django
migration
django-south
Apreche
sumber
sumber
Jawaban:
Cara bermigrasi menggunakan selatan.
Katakanlah kita punya dua aplikasi: umum dan spesifik:
Sekarang kami ingin memindahkan model common.models.cat ke aplikasi tertentu (tepatnya ke specific.models.cat). Pertama-tama buat perubahan dalam kode sumber lalu jalankan:
Sekarang kita perlu mengedit kedua file migrasi:
Sekarang kedua migrasi aplikasi menyadari perubahan dan hidup sedikit menyebalkan :-) Mengatur hubungan antara migrasi ini adalah kunci keberhasilan. Sekarang jika Anda melakukannya:
akan melakukan migrasi keduanya, dan
akan memigrasi semuanya.
Perhatikan bahwa untuk meningkatkan skema saya menggunakan aplikasi umum dan untuk menurunkan versi, saya menggunakan aplikasi tertentu. Itu karena cara ketergantungan di sini bekerja.
sumber
orm['contenttypes.contenttype'].objects.filter
garis di bagian belakang0003_create_cat
juga? Saya juga ingin berbagi tip. Jika Anda memiliki indeks, mereka perlu dimodifikasi juga. Dalam kasus saya itu adalah indeks unik, sehingga pemain depan saya terlihat seperti ini:db.delete_unique('common_cat', ['col1'])
db.rename_table('common_cat', 'specific_cat')
db.delete_unique('specific_cat', ['col1'])
orm['contenttypes.contenttype']
, Anda juga perlu menambahkan--freeze contenttypes
opsi keschemamigration
perintah Anda .python manage.py schemamigration specific create_cat --auto --freeze common
untuk mengakses model kucing dari aplikasi umum.Untuk membangun di Potr Czachur 's jawaban , situasi yang melibatkan ForeignKeys lebih rumit dan harus ditangani sedikit berbeda.
(Contoh berikut dibangun di atas
common
danspecific
aplikasi yang disebut dalam jawaban saat ini).akan berubah menjadi
Lari
akan menghasilkan migrasi berikut (saya sengaja mengabaikan perubahan Django ContentType — lihat jawaban yang dirujuk sebelumnya untuk cara mengatasinya):
Seperti yang Anda lihat, FK harus diubah untuk referensi tabel baru. Kita perlu menambahkan ketergantungan sehingga kita tahu urutan migrasi akan diterapkan (dan dengan demikian bahwa meja akan ada sebelum kita mencoba untuk menambahkan FK untuk itu) tapi kita juga perlu memastikan bergulir mundur bekerja juga karena yang ketergantungan bergantung pada arah sebaliknya .
Per dokumentasi Selatan ,
depends_on
akan memastikan bahwa0004_auto__add_cat
berjalan sebelum0009_auto__del_cat
ketika bermigrasi ke depan tetapi dalam urutan yang berlawanan ketika bermigrasi ke belakang . Jika kami meninggalkandb.rename_table('specific_cat', 'common_cat')
dispecific
rollback,common
rollback akan gagal ketika mencoba untuk memigrasi ForeignKey karena tabel tabel yang dirujuk tidak ada.Semoga ini lebih dekat dengan situasi "dunia nyata" daripada solusi yang ada dan seseorang akan menemukan ini bermanfaat. Bersulang!
sumber
Model tidak terlalu erat dengan aplikasi, jadi pemindahan cukup sederhana. Django menggunakan nama aplikasi dalam nama tabel database, jadi jika Anda ingin memindahkan aplikasi, Anda dapat mengubah nama tabel database melalui
ALTER TABLE
pernyataan SQL , atau - bahkan lebih sederhana - cukup gunakandb_table
parameter diMeta
kelas model Anda untuk merujuk ke nama lama.Jika Anda telah menggunakan ContentTypes atau hubungan umum di mana saja dalam kode Anda sejauh ini, Anda mungkin ingin mengubah nama tipe konten
app_label
yang menunjuk pada model yang bergerak, sehingga hubungan yang ada dipertahankan.Tentu saja, jika Anda tidak memiliki data sama sekali untuk disimpan, hal termudah untuk dilakukan adalah dengan menjatuhkan tabel database sepenuhnya dan berjalan
./manage.py syncdb
kembali.sumber
Inilah satu lagi perbaikan untuk solusi luar biasa Potr. Tambahkan berikut ini ke / 0003_create_cat tertentu
Kecuali jika dependensi ini ditetapkan ke Selatan, tidak akan menjamin bahwa
common_cat
tabel ada pada saat spesifik / 0003_create_cat dijalankan, melemparkandjango.db.utils.OperationalError: no such table: common_cat
kesalahan pada Anda.South menjalankan migrasi dalam urutan leksikografis kecuali ketergantungan ditetapkan secara eksplisit. Sejak
common
datang sebelumspecific
semuacommon
migrasi akan dijalankan sebelum penggantian nama tabel, jadi mungkin tidak akan mereproduksi dalam contoh asli yang ditunjukkan oleh Potr. Tetapi jika Anda mengubah namacommon
untukapp2
danspecific
untukapp1
Anda akan mengalami masalah ini.sumber
Proses yang saya selesaikan sejak saya kembali ke sini beberapa kali dan memutuskan untuk meresmikannya.
Ini awalnya dibangun di atas jawaban Potr Czachur dan jawaban Matt Briançon , menggunakan South 0.8.4
Langkah 1. Temukan hubungan kunci asing anak
Jadi dalam kasus yang diperluas ini, kami telah menemukan model terkait lainnya seperti:
Langkah 2. Buat migrasi
Langkah 3. Kontrol sumber: Komit perubahan sejauh ini.
Jadikan ini proses yang lebih berulang jika Anda mengalami konflik gabungan seperti rekan satu tim menulis migrasi pada aplikasi yang diperbarui.
Langkah 4. Tambahkan dependensi di antara migrasi.
Pada dasarnya
create_kittycat
tergantung pada keadaan saat ini dari segalanya, dan semuanya kemudian tergantung padacreate_kittycat
.Langkah 5. Tabel ganti nama perubahan yang ingin kita buat.
Langkah 6. Hanya jika Anda perlu mundur () untuk bekerja DAN mendapatkan KeyError berjalan mundur.
Langkah 7. Uji - apa yang berhasil untuk saya mungkin tidak cukup untuk situasi kehidupan nyata Anda :)
sumber
Jadi menggunakan respons asli dari @Potr di atas tidak berfungsi untuk saya di South 0.8.1 dan Django 1.5.1. Saya memposting apa yang berhasil bagi saya di bawah ini dengan harapan bermanfaat bagi orang lain.
sumber
Saya akan memberikan versi yang lebih eksplisit dari salah satu hal yang disarankan Daniel Roseman dalam jawabannya ...
Jika Anda hanya mengubah
db_table
atribut Meta dari model yang telah Anda pindahkan untuk menunjuk ke nama tabel yang ada (bukan nama baru yang Django akan berikan jika Anda menjatuhkan dan melakukan asyncdb
) maka Anda dapat menghindari migrasi Selatan yang rumit. misalnya:Asli:
Setelah pindah:
Sekarang Anda hanya perlu melakukan migrasi data untuk memperbarui
app_label
untukMyModel
didjango_content_type
meja dan Anda harus baik untuk pergi ...Jalankan
./manage.py datamigration django update_content_type
kemudian edit file yang dibuat Selatan untuk Anda:sumber