To jest trochę dziwne, ale postaram się wytłumaczyć najlepiej jak potrafię. Mam 2 modele: jeden reprezentujący wiadomość e-mail (wiadomość), a drugi to wiodąca sprzedaż (AffiliateLead). Kiedy formularz jest przesyłany za pośrednictwem witryny, system generuje lead, a następnie e-maile. Model wiadomości ma opcjonalne FK z powrotem do potencjalnego klienta. Z pliku modeli wiadomość:Dziwny IntegrityError na MySQL: # 1452
lead = models.ForeignKey('tracking.AffiliateLead', blank=True, null=True)
Teraz ta podstawowa powłoka działa:
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()
Jednak sam widok forma nie. To rzuca IntegrityError gdy próbuję zapisać wiadomość, która wskazuje na AffiliateLead:
(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`))')
Dzieje się tak pomimo faktu, że widok jest po prostu przybierające postać tworzenia i zapisywania AffiliateLead, następnie tworzenie i (stara) aby zapisać wiadomość. W rzeczywistości, gdy ten błąd zostanie zgłoszony, mogę przejść do MySQL i zobaczyć nowo utworzony lead. To nawet rzuca ten błąd w widoku kiedy ponownie odzyskać prowadzenie z DB bezpośrednio przed zapisaniem:
af_lead = AffiliateLead.objects.get(id = af_lead.id)
msg.lead = af_lead
msg.save()
Wreszcie, jeśli natychmiast odświeżyć (ponownego składania formularza), to działa. Brak IntegrityError. Jeśli mam Django wydrukować SQL, który robi, rzeczywiście widzę, że to INSERTing the AffiliateLead zanim spróbuje INSERT Message, a Message INSERT używa poprawnego ID AffiliateLead. Naprawdę jestem zdumiony w tym punkcie. Próbowałem nawet ręcznej obsługi transakcji bez skutku.
Dziękuję, pomogło to. Właśnie to widziałem. Niedawno uaktualniłem mój komputer, domyślam się, że mysql domyślnie używa InnoDB, gdzie kiedyś był MyISAM, więc było to bardzo zaskakujące zachowanie. –
Też miałem ten sam problem. Jednak w MySQL 5.5 domyślny typ tabeli to InnoDB. Cała moja strona została zbudowana w wersji 5.1 (a ja właśnie zaktualizowałem do wersji 5.5 przed uruchomieniem syncdb i loaddata na moim komputerze). Dlatego otrzymałem ten sam komunikat o błędzie (# 1452). Rozwiązaniem była zmiana typu DB na MyISAM w opcjach ustawień przed uruchomieniem synchronizacji db. Oto jak: http://djangosaur.tumblr.com/post/357759467/django-transaction-mysql-engine-innodb –