Django South - tablo zaten var


188

Güney ile başlamaya çalışıyorum. Mevcut bir veritabanım vardı ve South ( syncdb, schemamigration --initial) ekledim .

Sonra models.pybir alan eklemek için güncelledim ve koştu ./manage.py schemamigration myapp --auto. Alanı buluyor gibiydi ve bunu uygulayabileceğimi söyledi ./manage.py migrate myapp. Ancak, bunu yapmak hatayı verdi:

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

tablename, listelenen ilk tablodur models.py.

Django 1.2, Güney 0.7 kullanıyorum

Yanıtlar:


311

veritabanında zaten tablolar oluşturduğunuzdan, ilk geçişi sahte olarak çalıştırmanız yeterlidir

./manage.py migrate myapp --fake

modellerin şemasının veritabanındaki tabloların şemasıyla aynı olduğundan emin olun.


1
Anladım, teşekkürler. Aslında göç ve şematik göç değil, ama cevabınız beni doğru yöne getirdi.
Steve

1
hatam komutu OP'den kopyaladı, doğru komut ./manage.py migrate myapp --fake
Ashok

Bu çözüm benim durumumdaki sorunu çözmedi. Veritabanını değiştirmedim ve alan masada oluşturulmadığı için bazı görünümleri kilitledim. Yeni mülkü yorumlamak zorunda kaldım, her şeyi yeniden kurmak için tekrar sahte bir şekilde göç ettim ve ikinci denediğimde hala anlamadığım işe yaradı ... :)
Mc-

1
@Ashok belki de sondan schemamigrationönce migratedeğişiklikler yapmamız durumunda önce a'yı tekrar yapmamız gerektiğini belirtmelisiniz schemamigration.
Pierre de LESPINAY

3
Bu bana yardımcı olmadı. Veritabanımda zaten bir tablo vardı ve taşıma işleminden sonra sahte olan diğer tabloları eklemenin bir yolu yoktu. Tüm tabloları bırakmak ve taze başlamak zorunda kaldı.
Shailen

41

"Myapp_tablename" tablosu zaten ./manage.py myapp --fake'yi taşıdıktan sonra yükseltme durdurma hatası olmasına rağmen, DatabaseError böyle bir sütun göstermiyor: myapp_mymodel.added_field.

Tamamen aynı sorun var!

1.Önce buna neden olan taşıma numarasını kontrol edin . Varsayalım: 0010.

2. gerekenler:

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

birden fazla alan eksikse, her alan için tekrarlamanız gerekir.

3.Şimdi bir sürü yeni taşıma işlemine başlıyorsunuz, bu yüzden dosyalarını myapp / taşıma işlemlerinden kaldırın (birden fazla alan eklemeniz gerekiyorsa 0011 ve daha fazlası).

4. şunu çalıştırın:

./manage.py migrate myapp 0010

Şimdi ./manage.py göç myapp'ı deneyin

Eğer başarısız olmazsa, hazırsınız demektir. Herhangi bir alanın eksik olup olmadığını iki kez kontrol edin.

DÜZENLE:

Bu sorun, Güney'i yüklediğiniz bir üretim veritabanına ve diğer ortamlarda oluşturulan ilk geçişin zaten db'nizde bulunanları çoğaltırsa da oluşabilir. Çözüm burada çok daha kolay:

  1. İlk göçü taklit et:

    ./yönet göç myapp 0001 --fake

  2. Geri kalan taşıma işlemleriyle yuvarlanın:

    ./mgrate göçü yönetimi


10

Bu hatayla karşılaştığımda farklı bir nedeni vardı.

Benim durumumda South bir şekilde DB'mde _remake_table () ' da kullanılan geçici bir boş tablo bırakmıştı . Muhtemelen taşımamam gereken bir şekilde göçü bırakmıştım. Her durumda, bu _remake_table denilen sonraki her yeni göç, (), hata atma edildi sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already existsçünkü, vermedi zaten var ve orada olması gerekiyordu değildi.

_South_new biraz bana garip görünüyordu, bu yüzden DB'ye göz attım, masayı gördüm, başımı çizdim, South'un kaynağına_south_new_myapp_mymodel baktım , önemsiz olduğuna karar verdim, masayı düşürdüm ve her şey yolundaydı.


Ben de öyle gördüm ve bunu bulsaydım, yarım saatlik beyin zekasını kurtarırdım. Oldukça tatsız - ancak bunlar geçici geçiş tablolarıdır ve başarısız bir taşıma sırasında, muhtemelen inceleme amacıyla bırakılır. Maden, göç denemesi sırasında bazı db bütünlüğü sorunu nedeniyle meydana geldi.
Danny Staple

Bu daha yüksek olmalı! Şema işlemleri olmadan bir db kullanıyorsanız, bu oldukça kolay bir şekilde gerçekleşebilir
Yuji 'Tomita' Tomita

2

Modellerinizle @pielgrzym gibi veritabanınızla eşleşmeyen sorunlarınız varsa ve veritabanını en son models.py dosyasıyla eşleşecek şekilde otomatik olarak taşımak istiyorsanız (ve sırasında fikstürler tarafından yeniden oluşturulmayacak tüm verileri silmek istiyorsanız migrate):

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

Bu yalnızca en son models.pydosyanızda bulunan veritabanı tablolarını siler ve yeniden oluşturur , böylece veritabanınızda önceki syncdbs veya migrates'den çöp tablolarınız olabilir . Bunlardan kurtulmak için tüm bu göçlerden önce:

manage.py sqlclear myapp | manage.py sqlshell

Ve eğer hala veritabanınızda bir miktar CRUFT bırakırsa, yapmadan inspectdbönce bir models.pydosya oluşturmanız ve dosyayı (temizlemek istediğiniz tablolar ve uygulama için) oluşturmanız sqlclearve ardından orijinal modellerinizi geri yüklemeniz gerekir. --initialgöçün yaratılması ve göç edilmesi. Tüm bunlar, veritabanınızın ihtiyaç duyduğu belirli SQL lezzetiyle uğraşmaktan kaçınmak için.


1

Perform these steps in order may help you:

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

Yukarıdaki adım, varsayılan olarak taşıma klasörü oluşturur.

2) Python manage.py migrate apps.appname --fake

sahte bir göç oluşturur.

3) Python manage.py schemamigration apps.appname - otomatik

Ardından istediğiniz gibi alan ekleyebilir ve yukarıdaki komutu uygulayabilirsiniz.

4) Python manage.py migrate apps.appname


1

Mevcut bir veritabanınız ve uygulamanız varsa güney dönüşüm komutunu kullanabilirsiniz

./manage.py convert_to_south myapp

Bu, veritabanında olanlarda herhangi bir değişiklik yapmadan önce uygulanmalıdır .

Convert_to_south komutu yalnızca tamamen çalıştırdığınız ilk makinede çalışır. VCS'nize yaptığı ilk taşıma işlemlerini gerçekleştirdikten sonra ./manage.py migrate myapp 0001 --fake, kod tabanının bir kopyasına sahip olan her makinede çalışmanız gerekir (ilk önce modellerle ve şemalarla güncel olduklarından emin olun). ref: http://south.readthedocs.org/en/latest/convertinganapp.html


0

Geçici çözüm olarak, geçiş komut dosyasında Tablo oluşturma işlemini yorumlayabilirsiniz.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

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

Veya

Varolan tablo hiç satır içermiyorsa (boş), aşağıdaki gibi tabloyu silmeyi düşünün. (Bu düzeltme yalnızca tabloda satır yoksa önerilir) . Ayrıca, createModel işleminden önce bu işlemin yapıldığından emin olun.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

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

0

Bir çözüm daha (belki geçici bir çözüm).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

Örneğin.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Bu işlem ham sql sorgularındaki tüm geçişleri listeleyecektir. Varolan tabloyu oluşturan bölümden kaçınarak çalıştırmak istediğiniz sorguları seçebilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.