PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

Django:कई से कई जोड़ने के दौरान वफ़ादारी त्रुटि ()

क्या त्रुटि पुन:उत्पन्न की जा सकती है?

हाँ, आइए हम प्रसिद्ध Publication . का उपयोग करें और Article Django डॉक्स के मॉडल . फिर, आइए कुछ सूत्र बनाते हैं।

import threading
import random

def populate():

    for i in range(100):
        Article.objects.create(headline = 'headline{0}'.format(i))
        Publication.objects.create(title = 'title{0}'.format(i))

    print 'created objects'


class MyThread(threading.Thread):

    def run(self):
        for q in range(1,100):
            for i in range(1,5):
                pub = Publication.objects.all()[random.randint(1,2)]
                for j in range(1,5):
                    article = Article.objects.all()[random.randint(1,15)]
                    pub.article_set.add(article)

            print self.name


Article.objects.all().delete()
Publication.objects.all().delete()
populate()
thrd1 = MyThread()
thrd2 = MyThread()
thrd3 = MyThread()

thrd1.start()
thrd2.start()
thrd3.start()

आप निश्चित रूप से बग रिपोर्ट में रिपोर्ट किए गए प्रकार के अद्वितीय कुंजी बाधा उल्लंघन देख सकते हैं। . यदि आप उन्हें नहीं देखते हैं, तो थ्रेड्स या पुनरावृत्तियों की संख्या बढ़ाने का प्रयास करें।

क्या कोई समाधान है?

हाँ। through का उपयोग करें मॉडल और get_or_create . django डॉक्स में उदाहरण से अनुकूलित model.py यहां दिया गया है।

class Publication(models.Model):
    title = models.CharField(max_length=30)

    def __str__(self):              # __unicode__ on Python 2
        return self.title

    class Meta:
        ordering = ('title',)

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication, through='ArticlePublication')

    def __str__(self):              # __unicode__ on Python 2
        return self.headline

    class Meta:
        ordering = ('headline',)

class ArticlePublication(models.Model):
    article = models.ForeignKey('Article', on_delete=models.CASCADE)
    publication = models.ForeignKey('Publication', on_delete=models.CASCADE)
    class Meta:
        unique_together = ('article','publication')

यहाँ नया थ्रेडिंग वर्ग है जो ऊपर वाले का एक संशोधन है।

class MyThread2(threading.Thread):

    def run(self):
        for q in range(1,100):
            for i in range(1,5):
                pub = Publication.objects.all()[random.randint(1,2)]
                for j in range(1,5):
                    article = Article.objects.all()[random.randint(1,15)]
                    ap , c = ArticlePublication.objects.get_or_create(article=article, publication=pub)
            print 'Get  or create', self.name

आप पाएंगे कि अपवाद अब दिखाई नहीं देता है। पुनरावृत्तियों की संख्या बढ़ाने के लिए स्वतंत्र महसूस करें। मैं केवल get_or_create . के साथ 1000 तक गया इसने अपवाद नहीं फेंका। हालांकि add() आमतौर पर 20 पुनरावृत्तियों के साथ एक अपवाद फेंक दिया।

यह क्यों काम करता है?

क्योंकि get_or_create परमाणु है।

अपडेट करें: धन्यवाद @louis यह इंगित करने के लिए कि मॉडल के माध्यम से वास्तव में समाप्त किया जा सकता है। इस प्रकार get_or_create MyThread2 . में के रूप में बदला जा सकता है।

ap , c = article.publications.through.objects.get_or_create(
            article=article, publication=pub)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL में डेटाबेस और टेबल्स को कैसे लिस्ट करें

  2. पासवर्ड के बिना psql कमांड के साथ बैच फ़ाइल चलाएँ

  3. Mac पर Homebrew के साथ PostgreSQL

  4. पीजी-वादे में स्कीमा कैसे सेट करें

  5. पोस्टग्रेस्क्ल में जहां क्लॉज में कॉलम एलियासेस तक पहुंचें