Django'da bir fikstür yüklerken içerik türleriyle ilgili sorunlar


104

İçerik türü çakışmaları nedeniyle Django fikstürlerini MySQL veritabanıma yüklemekte sorun yaşıyorum. İlk önce verileri yalnızca uygulamamdan şu şekilde atmayı denedim:

./manage.py dumpdata escola > fixture.json

ancak "escola" uygulamam diğer uygulamalardan tablolar kullandığı için yabancı anahtar sorunlarını kaçırmaya devam ettim. Şuna gelene kadar ek uygulamalar eklemeye devam ettim:

./manage.py dumpdata contenttypes auth escola > fixture.json

Şimdi, verileri bir test fikstürü olarak yüklemeye çalıştığımda sorun şu kısıtlama ihlalidir:

IntegrityError: (1062, "Duplicate entry 'escola-t23aluno' for key 2")

Görünüşe göre sorun, Django'nun donanımdaki birincil anahtar değerleriyle çelişen farklı birincil anahtar değerlerine sahip içerik türlerini dinamik olarak yeniden oluşturmaya çalışmasıdır. Bu, burada belgelenen hatayla aynı görünüyor: http://code.djangoproject.com/ticket/7052

Sorun şu ki, önerilen geçici çözüm zaten yapmakta olduğum contenttypes uygulamasını dökmek !? Ne oluyor? Herhangi bir fark yaratırsa, burada belgelendiği gibi bazı özel model izinlerim var: http://docs.djangoproject.com/en/dev/ref/models/options/#permissions

Yanıtlar:


148

manage.py dumpdata --naturalyabancı anahtarların daha dayanıklı bir temsilini kullanacaktır. Django'da bunlara "doğal anahtarlar" denir. Örneğin:

  • Permission.codename lehine kullanılır Permission.id
  • User.username lehine kullanılır User.id

Daha fazlasını okuyun: "django nesnelerini serileştirme" içindeki doğal anahtarlar bölümü

Aşağıdakiler için başka yararlı argümanlar dumpdata:

  • --indent=4 insanlar tarafından okunabilir hale getirin.
  • -e sessions oturum verilerini hariç tut
  • -e admin yönetici sitesinde yönetici eylemlerinin geçmişini hariç tut
  • -e contenttypes -e auth.Permissionher seferinde şemadan otomatik olarak yeniden oluşturulan nesneleri hariç tutun syncdb. Sadece birlikte kullanın, --naturalaksi takdirde kötü hizalanmış kimlik numaralarıyla karşılaşabilirsiniz.

1
@skyjur neden hep kullanmak -e contenttypes -e auth.permissionile --natural? Sadece --naturalseçenek olmadan denedim ve işe yaradı. Ayrıca buradaki dokümantasyon , DUMPING auth.permission ve contenttypes.
wlnirvana

6
@winirvana çünkü sıfırdan başladıktan ve syncdb yaptıktan sonra, yeni oluşturulmuş ContentTypeve Permissioneskisi gibi aynı kimliği elde etme garantisi yoktur. Veri dökümünüz, verileri yükleyeceğiniz başka bir veritabanında farklı nesnelere başvurabilecek kimlikler içerir. Aşağıdaki nedenlerden birinden dolayı sizin için işe yarayabilir: 1) verileriniz bu nesnelere herhangi bir referansa sahip değildi 2) Orijinal İzin / İçerik Tiplerinin kimlikleri korundu 3) yükleme verileriniz başarılıydı ancak gerçekte nesneler nedeniyle bozuk verileriniz var yanlış nesnelere atıfta bulunuyorsunuz ve henüz bunu bilmiyorsunuz
Kayak

12
Bayrak --naturalartık --natural-foreign(ve --natural-primary) lehine kullanımdan kaldırıldı
frnhr

16
Son komut şu şekilde olabilir:manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4 > project_dump.json
Paolo

4
--naturalartık tamamen kaldırıldı, kullanımdan kaldırıldı. Kullanın --natural-foreignveya --natural-primarybunun yerine.
Code-Apprentice

35

Evet, bu gerçekten sinir bozucu. Bir süre fikstürü yüklemeden önce contenttypes uygulamasında bir "manage.py sıfırlaması" yaparak (dökülmüş sürümden farklı olan, otomatik olarak oluşturulmuş içerik türleri verilerinden kurtulmak için) bunun üzerinde çalıştım. Bu işe yaradı, ancak sonunda zorluklardan bıktım ve fikstürleri tamamen düz SQL dökümleri lehine terk ettim (tabii ki, o zaman DB taşınabilirliğini kaybedersiniz).

güncelleme - en iyi cevap, aşağıdaki cevapta belirtildiği gibi , --naturalbayrağı kullanmaktır dumpdata. Bu cevabı yazdığımda o bayrak henüz yoktu.


3
Ben de bununla karşılaşıyordum, contenttypes uygulamasını sıfırlamak da benim için çalıştı. Bahşiş için teşekkürler!
Beau

Onları nasıl sıfırladın? Test vakası sınıfında mı? Bana bir örnek ver lütfen
Oleg Tarasenko

4
Birim testleri için armatürleri kullanmıyorum, genellikle bir setup () yönteminde ORM'yi kullanarak test verileri oluşturuyorum çünkü testlerle uyumlu tutmak daha kolay. Bu yüzden bunu bir TestCase sınıfında yapmak zorunda kalmadım, ancak eminim ki Django'nun TestCase sınıfının kodunu karıştırırsanız, syncdb sonrası ve bir alt sınıftaki fikstür yüklemesinden önce bir sıfırlamanın nasıl gerçekleştirileceğini anlayabilirsiniz. Benim için sadece "./manage.py loaddata my_fixture" öncesinde bir bash komut dosyasında "./manage.py içerik türlerini sıfırla" idi.
Carl Meyer

32

Fikstür oluştururken içerik türlerini atlamayı deneyin:

./manage.py dumpdata --exclude contenttypes > fixture.json

Birim testleri için benzer bir durumda benim için çalıştı, içerik türleriyle ilgili anlayışınız gerçekten yardımcı oldu!


31

Buradaki cevapların hepsi eski ... 2017 itibariyle, en iyi cevap:

manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission --indent 4

11

MySQL kullanmıyordum, bunun yerine canlı bir sunucudan bazı verileri sqlite'a aktarıyordum. Yapmadan contenttypesönce uygulama verilerini temizlemek loaddatahile yaptı:

from django.contrib.contenttypes.models import ContentType
ContentType.objects.all().delete()
quit()

Ve sonra

python manage.py loaddata data.json

django.core.exceptions.ImproperlyConfigured: INSTALLED_APPS ayarı istendi, ancak ayarlar yapılandırılmadı. Ayarlara erişmeden önce ortam değişkenini DJANGO_SETTINGS_MODULE tanımlamalı veya settings.configure () öğesini çağırmalısınız.
Barney

Muhtemelen en iyi, özel bir yönetim komutunun içinde çalışır.
Barney

10

Döküm dosyamı yüklemeden önce, içerik türleri uygulamasını birim testinden sıfırlayarak bu sorunu test durumlarımda çözdüm. Carl bunu zaten manage.pykomutu kullanarak önerdi ve ben de aynı şeyi yalnızca call_commandyöntemi kullanarak yapıyorum :

>>> from django.core import management
>>> management.call_command("flush", verbosity=0, interactive=False)
>>> management.call_command("reset", "contenttypes", verbosity=0, interactive=False)
>>> management.call_command("loaddata", "full_test_data.json", verbosity=0)

Benim full_test_data.jsonfikstürü contenttypes uygulaması dökümü içeren deney verilerinin geri kalanına karşılık gelir o. Uygulamayı yüklemeden önce sıfırlayarak yinelenen anahtarı engeller IntegrityError.


7
python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth.Permission --exclude=admin.logentry --exclude=sessions.session --indent 4 > initial_data.json

Bu benim için çalışıyor. Burada gerçek modellerden her şeyi dışlıyorum.

  • Oluşturduğunuz modellerin dışında başka bir model görürseniz, bunları güvenle hariç tutabilirsiniz. Bu yaklaşımın bir dezavantajı, günlük verilerinin yanı sıra kimlik doğrulama verilerini de kaybetmenizdir.

6

Herhangi bir yabancı anahtarı ve çoktan çoğa ilişkileri temsil etmek için doğal anahtarlar kullanmanız gerekir. Ayrıca, dışlamak için iyi bir fikir olabilir sessiontabloyu sessionsuygulaması ve logentrymasa adminapp.

Django 1.7+

python manage.py dumpdata --natural-foreign --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Django <1.7

python manage.py dumpdata --natural --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

Göre Django belgeleri , --naturalopsiyon böylece, sürüm 1.7 önerilmemektedir olmuştur --natural-foreignyerine kullanılmalıdır.

Bu nesnenin serileştirilmiş verilerindeki birincil anahtarı atlayabilirsiniz, çünkü serileştirme sırasında --natural-primarybayrak geçerek hesaplanabilir .

python manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions.session --indent 4 > fixture.json

2
./manage.py dumpdata app.Model --natural-foreign

değişecek

  "content_type": 123

-e

  "content_type": [
    "app_label",
    "model"
  ],

Ve fikstür TestCaseşimdilik çalışıyor


2

Django 2.2.5

python manage.py dumpdata --exclude=contenttypes > datadump.json

Bana yardımcı oldu


Veri yükleme olduğunda sorun yaratacak, yeni veritabanında içerik türü ile uyuşmayabilir
yang zhou

1

Az önce anladığım başka bir olası cevap vereceğim. Belki OP'ye yardımcı olur, belki başkasına yardımcı olur.

Çoktan çoğa bir ilişki tablom var. Bir birincil anahtarı ve diğer tabloların iki yabancı anahtarı vardır. Fikstürde, iki yabancı anahtarı zaten tablodaki farklı bir pk ile başka bir girişle aynı olan bir girişim varsa, başarısız olacağını buldum. M2M ilişki tablolarında iki yabancı anahtar için "birlikte benzersiz" vardır.

Öyleyse, kopan bir M2M ilişkisiyse, eklediği yabancı anahtarlara bakın, bu FK çiftinin zaten farklı bir PK altında listelenip listelenmediğini görmek için veritabanınıza bakın.


1

Bu gerçekten çok can sıkıcı .. Her seferinde bununla ısırılıyorum.

Verileri --exclude contenttypes ve - natural ile dökmeye çalıştım, her zaman sorunla karşılaşıyorum ..

Benim için en iyi truncate table django_content_type;sonuç, syncdb'den sonra basitçe bir yapmak ve SONRA verileri yüklemek.

Elbette initial_data.json otomatik yüklemesi için fallball'unuz.


Benim için, veri yükleme işleminden önce tabloyu kesmek sadece farklı hatalara neden olur. Bu teknikte şans yok.
shacker

1

Benzer bir hatayla bazen daha önce karşılaşmıştım. Gerekli masaları oluşturmadan önce armatürleri yüklemeye çalıştığım ortaya çıktı. Ben de yaptım:

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py loaddata fixtures/initial_data.json

Ve bir cazibe gibi çalıştı


0

Benim durumumda fikstürü test amacıyla kullanmak için auth( ./manage.py dumpddata auth > fixtures/auth.json) 'den verileri döktüm.

Geliştirme devam etti ve tanımladığım modellerin çoğunu kaldırdım models.pyve işte o zaman bu can sıkıcı sorunu görmeye başladım.

Benim çözümüm auth.json fikstürünü yeniden oluşturmaktı. Bu, sahip auth.permissionolduğum eski modellerle ilgili birçok girişi kaldırmıştı .


0

Yukarıdan her yöntemi denedim, Benim için hiçbir şey işe yaramadı. Tam kimlik doğrulama modelini dışlamam gerekiyor ve sorunsuz çalışıyor.

python manage.py dumpdata --natural-primary --exclude=contenttypes --exclude=auth --exclude=admin.logentry --exclude=sessions.session --indent 4 > live.json
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.