2011-01-13 11 views
11

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.

Odpowiedz

13

Nie jestem do końca pewien, dlaczego tak się stało, ale wydaje mi się, że znalazłem rozwiązanie. Używam South do zarządzania DB; utworzyła Wiadomości jako InnoDB i AffiliateLead jako MyISAM. Zmiana tabeli AffiliateLead na InnoDB zakończyła działanie IntegrityErrors. Mam nadzieję, że to pomoże komuś innemu.

+0

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. –

+0

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 –