2010-10-05 25 views
1

J'ai une application Django relativement simple, avec une utilisation assez lourde qui est responsable d'une certaine concurrence dans les opérations db.IntegrityError avec les relations Django m2m

J'ai un modèle Post avec un m2m pour un modèle Tag.

Une seule ligne dans mon code, p.add(t) est à l'origine à plusieurs reprises des exceptions de MySQL (où p est un exemple Post et t est une instance de Tag.)

IntegrityError: (1062, "Duplicate entry '329051-1827414' for key 'post_id'") 

Lorsque cela est élevé, je peux exécuter manuellement ce p.add(t) avec succès , il doit donc faire avec un état particulier que les db/app sont au moment de l'exécution normale. Il arrive environ une fois par 1000 tentatives d'ajout de balises, sans aucun motif que je peux détecter (c.-à-d. Les deux nombres dans la paire "329051-1827414" de l'exemple)

Un CHECK TABLE dans mysql sur le tableau correspondant montre qu'ils sont tous apparemment OK.

Des idées?

Répondre

1

Habituellement, vous voyez des erreurs comme cela lorsque vous essayez d'ajouter à une table intermédiaire si la ligne ajoutée ajoute la contrainte unique-ensemble pour les FK. Je devine que dans l'exemple que vous avez fourni "329051" est un id de poste et "1827414" est un identifiant de balise.

Normalement dans Django vous pouvez appeler la méthode add() à plusieurs reprises pour ajouter la même instance et Django s'occupe de tout pour vous. Je suppose que le gestionnaire de modèle conserve un état pour l'aider à déterminer si chaque add() représente une ligne nouvelle ou existante et si la ligne semble être nouvelle, elle tente une insertion.

Cela en soi n'explique pas pourquoi vous obtenez l'erreur. Vous mentionnez "est responsable d'une certaine concurrence dans les opérations db.". Sans savoir ce que cela signifie, je suppose que vous pourriez obtenir une condition de concurrence où plusieurs threads/processus tentent d'ajouter la même nouvelle balise en même temps et les deux tentent des insertions.

0

Je pense que je rencontre un problème similaire dans mon application - Si j'envoie deux requêtes identiques pour ajouter une relation m2m (par exemple tag dans mon cas), j'obtiens cette erreur car la table m2m a une contrainte unique sur (utilisateur, tag). Je devine que le serveur traite les fonctions .add en même temps.

if not already in database: 
    # Both invocations reach here because the next line takes some time to process. 
    create m2m row 

Je ne sais pas comment cela peut être corrigé.