2011-01-13 15 views
11

Bu garip bir şey ama elimden geldiğince açıklamaya çalışacağım. 2 modelim var: biri e-posta mesajını (Mesaj), diğerini bir satış liderini (AffiliateLead) temsil ediyor. Site aracılığıyla bir form gönderildiğinde, sistem bir müşteri adayı oluşturur ve daha sonra e-postalar oluşturur. Mesaj modelinde isteğe bağlı bir FK'nin Kurşun'a geri dönüşü vardır.Odd IntegrityError on MySQL: # 1452

lead = models.ForeignKey('tracking.AffiliateLead', blank=True, null=True) 

Şimdi, bu temel kabuk çalışır:: Mesaj modelleri Dosyadan'ı

from tracking.models import Affiliate, AffiliateLead 
from messages.models import Message 
from django.contrib.auth.models import User 

u = User.objects.get(username='testguy') 
a = Affiliate.objects.get(affiliate_id = 'ACD023') 
l = AffiliateLead(affiliate = a) 
l.save() 
m = Message(recipient=u, sender=u, subject='s', body='a', lead=l) 
m.save() 

Ancak form görünümü kendisi yapmaz. Bir AffiliateLead işaret eden bir mesajı kaydetmeye çalıştığımda Bir IntegrityError atar:

(1452, 'Cannot add or update a child row: a foreign key constraint fails (`app`.`messages_message`, CONSTRAINT `lead_id_refs_id_6bc546751c1f96` FOREIGN KEY (`lead_id`) REFERENCES `tracking_affiliatelead` (`id`))') 

Bu görüş sadece, şekil alıyor oluşturup AffiliateLead tasarruf ardından oluşturma ve olmasına rağmen olduğu (çalışıyor) Mesajı kaydetmek için Aslında, bu hata atıldığında, MySQL'e gidebilir ve yeni oluşturulan kurumu görebilirim. Hatta ben zaman hemen kaydetmeden önce DB'den kurşun yeniden almak görünümünde bu hatayı atar:

af_lead = AffiliateLead.objects.get(id = af_lead.id) 
msg.lead = af_lead 
msg.save() 

Son olarak, ben hemen yenilemek if (yeniden göndermekten formu), işe yarıyor. IntegrityError yok. Yaptığım SQL'i Django'yu yazdırırsam, gerçekten mesajın INSERT'i göndermeden önce AffiliateLead'i INSERTing olduğunu ve Message INSERT'in doğru AffiliateLead ID'sini kullandığını görebiliyorum. Bu noktada gerçekten çok şaşırdım. Manuel işlem işlemlerini boşuna bile denedim.

cevap

13

Neden böyle olduğundan emin değilim, ama bir çözüm bulmuş gibiyim. DB'yi yönetmek için Güney kullanıyorum; InnoDB ve AffiliateLead adlı mesajları MyISAM olarak oluşturdu. AffiliateLead tablosunu InnoDB'ye değiştirmek IntegrityErrors'u sonlandırdı. Umarım bu bir başkasına yardım eder.

+0

Teşekkürler, bu yardımcı oldu. Tam olarak gördüğüm şey bu. Son zamanlarda bilgisayarımı yükselttim, mysql şimdi MyISAM olduğu yerde şimdi InnoDB için varsayılan olduğunu tahmin ediyorum bu yüzden bu çok şaşırtıcı bir davranıştı. –

+0

Ayrıca bu sorunu da yaşadım. Ancak, MySQL 5.5'te varsayılan tablo türü InnoDB'dir. Tüm sitem 5.1 ile kuruldu (ve makinemde syncdb ve loaddata çalıştırmadan önce 5.5'e yükseltildim). Bu yüzden aynı hata mesajını alıyorum (# 1452). Çözüm, senkronizasyon db'yi çalıştırmadan önce ayarların seçeneklerinde DB Tipini MyISAM olarak değiştirmekti. İşte nasıl: http://djangosaur.tumblr.com/post/357759467/django-transaction-mysql-engine-innodb –