Django South - tabel sudah ada

188

Saya mencoba memulai dengan Selatan. Saya memiliki database yang sudah ada dan saya menambahkan Selatan ( syncdb, schemamigration --initial).

Kemudian, saya memperbarui models.pyuntuk menambahkan bidang dan berlari ./manage.py schemamigration myapp --auto. Tampaknya menemukan lapangan dan berkata saya bisa menerapkan ini dengan ./manage.py migrate myapp. Tetapi, melakukan itu memberi kesalahan:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablenameadalah tabel pertama yang terdaftar di models.py.

Saya menjalankan Django 1.2, South 0.7

Steve
sumber

Jawaban:

311

karena Anda sudah memiliki tabel yang dibuat dalam database, Anda hanya perlu menjalankan migrasi awal sebagai palsu

./manage.py migrate myapp --fake

pastikan bahwa skema model sama dengan skema tabel dalam database.

Ashok
sumber
1
Terima kasih, terima kasih. Ini sebenarnya bermigrasi dan bukan skemamigrasi, tetapi jawaban Anda membuat saya ke arah yang benar.
Steve
1
kesalahan saya baru saja menyalin perintah dari OP, perintah yang benar ./manage.py migrasi myapp --fake
Ashok
Solusi ini tidak menyelesaikan masalah dalam kasus saya. Saya tidak mengubah database dan membuat beberapa tampilan gagal karena bidang tidak dibuat di atas meja. Saya harus mengomentari properti baru, bermigrasi dengan palsu lagi untuk membangun kembali semuanya, dan kedua kalinya saya mencobanya ternyata tidak berfungsi yang saya masih belum mengerti ... :)
Mc
1
@Ashok mungkin Anda juga harus menentukan kita harus mengulang schemamigrationsebelum migratekita harus melakukan modifikasi sebelum yang terakhir schemamigration.
Pierre de LESPINAY
3
Ini tidak membantu saya. Saya sudah memiliki tabel di database saya, dan setelah memalsukan migrasi, tidak ada cara untuk menambahkan tabel lain yang dipalsukan. Saya harus menjatuhkan semua tabel dan mulai yang baru.
Shailen
41

Meskipun tabel "myapp_tablename" sudah ada peningkatan berhenti kesalahan setelah saya lakukan ./manage.py migrasi myapp --fake, DatabaseError tidak menunjukkan kolom seperti itu: myapp_mymodel.added_field.

Punya masalah yang sama persis!

1. Pertama-tama periksa nomor migrasi yang menyebabkan ini. Mari kita asumsikan: 0010.

2. Anda perlu:

./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp

jika ada lebih dari satu bidang yang hilang Anda harus mengulanginya untuk setiap bidang.

3.Sekarang kamu mendarat dengan sekelompok migrasi baru jadi hapus file-file mereka dari myapp / migrasi (0011 dan selanjutnya jika kamu perlu menambahkan banyak bidang).

4.Jalankan ini:

./manage.py migrate myapp 0010

Sekarang coba ./manage.py migrasi aplikasi saya

Jika tidak gagal, Anda siap. Cukup centang dua kali jika ada bidang yang tidak hilang.

EDIT:

Masalah ini juga dapat terjadi ketika Anda memiliki basis data produksi tempat Anda menginstal Selatan dan migrasi awal pertama yang dibuat dalam duplikat lingkungan lain apa yang sudah Anda miliki di db. Solusinya jauh lebih mudah di sini:

  1. Palsu migrasi pertama:

    ./Manage melakukan migrasi myapp 0001 --palsu

  2. Gulung dengan sisa migrasi:

    ./Mengelola migrasi aplikasi saya

pielgrzym
sumber
10

Ketika saya mengalami kesalahan ini, ada penyebab lain.

Dalam kasus saya Selatan entah bagaimana meninggalkan dalam DB saya tabel kosong sementara, yang digunakan dalam _remake_table () . Mungkin saya telah membatalkan migrasi dengan cara yang seharusnya tidak saya lakukan. Bagaimanapun, setiap migrasi baru berikutnya, ketika disebut _remake_table (), melempar kesalahan sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, karena memang sudah ada dan tidak seharusnya ada di sana.

Bit _south_new tampak aneh bagi saya, jadi saya melihat-lihat DB saya, melihat meja _south_new_myapp_mymodel, menggaruk kepala saya, melihat sumber Selatan , memutuskan itu sampah, menjatuhkan meja, dan semuanya baik-baik saja.

ben penulis
sumber
Inilah yang saya lihat, dan seandainya saya menemukan ini, akan menyelamatkan saya setengah jam dari sakit otak. Cukup tidak menyenangkan - tetapi ini adalah tabel migrasi sementara, dan dibiarkan selama migrasi gagal, mungkin untuk keperluan inspeksi. Milik saya terjadi karena beberapa masalah integritas db selama upaya migrasi.
Danny Staple
Ini harus lebih tinggi! Jika Anda menggunakan db tanpa transaksi skema, ini bisa terjadi dengan mudah
Yuji 'Tomita' Tomita
2

Jika Anda memiliki masalah dengan model Anda yang tidak cocok dengan basis data Anda, seperti @pielgrzym, dan Anda ingin memigrasi basis data secara otomatis agar sesuai dengan file models.py terbaru (dan menghapus data apa pun yang tidak akan dibuat kembali dengan perlengkapan selama migrate):

manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp

Ini hanya akan menghapus dan membuat ulang tabel database yang ada di models.pyfile terbaru Anda , sehingga Anda mungkin memiliki tabel sampah di database Anda dari sebelumnyasyncdb s atau migrates. Untuk menghilangkannya, awali semua migrasi ini dengan:

manage.py sqlclear myapp | manage.py sqlshell

Dan jika itu masih menyisakan beberapa CRUFT tergeletak di database Anda maka Anda harus melakukan inspectdbdan membuat models.pyfile dari itu (untuk tabel dan aplikasi yang ingin Anda hapus) sebelum melakukan sqlcleardan kemudian mengembalikan models.py asli Anda sebelum membuat --initialmigrasi dan bermigrasi ke sana. Semua ini untuk menghindari bermain-main dengan rasa khusus SQL yang dibutuhkan database Anda.

hobs
sumber
1

Perform these steps in order may help you:

1) python manage.py schemamigration apps.appname --initial

Langkah di atas membuat folder migrasi sebagai default.

2) python manage.py migrasi apps.appname --fake

menghasilkan migrasi palsu.

3) python manage.py schemamigration apps.appname --auto

Kemudian Anda dapat menambahkan bidang seperti yang Anda inginkan dan melakukan perintah di atas.

4) python manage.py melakukan migrasi apps.appname

Vijesh Venugopal
sumber
1

Jika Anda memiliki database dan aplikasi yang sudah ada, Anda dapat menggunakan perintah konversi selatan

./manage.py convert_to_south myapp

Ini harus diterapkan sebelum Anda melakukan perubahan apa pun yang sudah ada dalam database.

Perintah convert_to_south hanya berfungsi sepenuhnya pada mesin pertama Anda menjalankannya. Setelah Anda melakukan migrasi awal yang dibuatnya ke dalam VCS Anda, Anda harus menjalankan ./manage.py migrate myapp 0001 --fakepada setiap mesin yang memiliki salinan basis kode (pastikan terlebih dahulu mereka memiliki model dan skema). ref: http://south.readthedocs.org/en/latest/convertinganapp.html

Tommy Strand
sumber
0

Sebagai solusi sementara, Anda dapat mengomentari pembuatan Tabel di skrip migrasi.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

    operations = [
        #migrations.CreateModel(
        #    name='TABLE',
        #    fields=[
        #            ....
        #            ....
        #    ],
        #),
        ....
        ....

Atau

Jika tabel yang ada tidak mengandung baris (kosong), maka pertimbangkan untuk menghapus tabel seperti di bawah ini. (Perbaikan ini disarankan hanya jika tabel tidak berisi baris) . Pastikan juga operasi ini sebelum operasi createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]
SuperNova
sumber
0

Satu lagi solusi (mungkin solusi sementara).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

misalnya.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Ini akan mencantumkan semua migrasi dalam kueri sql mentah. Anda bisa memilih kueri yang ingin Anda jalankan menghindari bagian yang membuat tabel yang ada

SuperNova
sumber