2011-01-13 4 views
11

C'est un peu bizarre mais je vais essayer d'expliquer le mieux possible. J'ai 2 modèles: un représentant un message électronique (Message), l'autre un responsable des ventes (AffiliateLead). Lorsqu'un formulaire est soumis via le site, le système génère une piste, puis des e-mails. Le modèle de message a un FK optionnel de retour au prospect. A partir du fichier modèles de message:Odd IntegrityError sur MySQL: # 1452

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

Maintenant, cette coquille de base fonctionne:

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() 

Cependant, la vue forme elle-même ne fonctionne pas. Il jette un IntegrityError lorsque je tente de sauver un message qui pointe vers un 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`))') 

Ceci malgré le fait que la vue est tout simplement en prenant la forme, la création et l'enregistrement du AffiliateLead, puis en créant et (essayer) pour enregistrer le message. En fait, quand cette erreur est levée, je peux aller dans MySQL et voir le lead nouvellement créé. Il jette même cette erreur dans la vue quand je re-récupérer la tête du DB immédiatement avant d'enregistrer:

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

Enfin, si je Réactualise immédiatement (re-soumission du formulaire), cela fonctionne. Non IntegrityError. Si Django imprime le SQL qu'il fait, je peux en effet voir qu'il INSERT le AffiliateLead avant qu'il essaye d'INSÉRER le message, et le message INSERT utilise le bon AffiliateLead ID. Je suis vraiment perplexe à ce point. J'ai même essayé la manipulation manuelle des transactions en vain.

Répondre

13

Je ne sais pas exactement pourquoi c'est arrivé, mais j'ai semblé trouver une solution. J'utilise South pour gérer la DB; il a créé des messages comme InnoDB et AffiliateLead comme MyISAM. La modification de la table AffiliateLead en InnoDB a mis fin aux IntegrityErrors. J'espère que ceci aide quelqu'un d'autre.

+0

Merci, cela m'a aidé. C'est exactement ce que je voyais. Récemment mis à jour mon ordinateur, je suppose que mysql est par défaut à InnoDB maintenant où il était auparavant MyISAM donc c'était un comportement très surprenant. –

+0

J'ai aussi eu ce même problème. Cependant, dans MySQL 5.5, le type de table par défaut est InnoDB. Mon site entier a été construit avec 5.1 (et je venais de passer à 5.5 avant d'exécuter syncdb et loaddata sur ma machine). Par conséquent, je recevais ce même message d'erreur (# 1452). La solution consistait à modifier le type de base de données en MyISAM dans les options des paramètres avant d'exécuter db de synchronisation. Voici comment: http://djangosaur.tumblr.com/post/357759467/django-transaction-mysql-engine-innodb –