2015-06-11 5 views
7

मैं अपने यूनिट परीक्षणों में डेटाबेस समस्या में भाग रहा हूं। मुझे लगता है कि जिस तरह से मैं टेस्टकेस और सेटअपडेटा का उपयोग कर रहा हूं उसके साथ कुछ करना है।Django टेस्ट: Postgres पर setUpTestData फेंकता है: "डुप्लिकेट कुंजी मान अद्वितीय बाधा का उल्लंघन करता है"

जब मैं कुछ मूल्यों के साथ अपने परीक्षण डेटा सेट करने का प्रयास, परीक्षण निम्न त्रुटि फेंक:

django.db.utils.IntegrityError: duplicate key value violates unique constraint 

... 

psycopg2.IntegrityError: duplicate key value violates unique constraint "InventoryLogs_productgroup_product_name_48ec6f8d_uniq" 
DETAIL: Key (product_name)=(Almonds) already exists. 

मैं अपने प्राथमिक कुंजी के सभी बदल गया है और यह ठीक चल रहा है। यह किसी भी परीक्षण को प्रभावित नहीं करता है।

हालांकि, मुझे चिंता है कि मैं कुछ गलत कर रहा हूं। जब यह पहली बार हुआ, तो मैंने अपने ऐप पर एक घंटे के लायक काम को उलट दिया (नोब के लिए इतना कोड नहीं), जिसने समस्या को सही किया।

तब जब मैंने परिवर्तनों को वापस लिखा, तो एक ही समस्या स्वयं को प्रस्तुत की गई। टेस्टकेस नीचे चिपकाया गया है। सॉर्ट्रेकॉर्ड आइटम जोड़ने के बाद यह समस्या उत्पन्न होती है, लेकिन इसके ऊपर की वस्तुओं से मेल खाती है।

मैं अपने परीक्षणों में प्राथमिक कुंजी और यूआरएल को बदलना और बदलना नहीं चाहता, इसलिए अगर कोई इसका उपयोग कर रहा हूं, तो कृपया मुझे कुछ मदद मिलती है, कृपया मेरी मदद करें। धन्यवाद!

testcase

class DetailsPageTest(TestCase): 


@classmethod 
def setUpTestData(cls): 

    cls.product1 = ProductGroup.objects.create(
         product_name="Almonds" 
         ) 
    cls.variety1 = Variety.objects.create(
         product_group = cls.product1, 
         variety_name = "non pareil", 
         husked = False, 
         finished = False, 
         ) 

    cls.supplier1 = Supplier.objects.create(
         company_name = "Acme", 
         company_location = "Acme Acres", 
         contact_info = "Call me!" 
         ) 

    cls.shipment1 = Purchase.objects.create(
         tag=9, 
         shipment_id=9999, 
         supplier_id = cls.supplier1, 
         purchase_date='2015-01-09', 
         purchase_price=9.99, 
         product_name=cls.variety1, 
         pieces=99, 
         kgs=999, 
         crackout_estimate=99.9 
         ) 
    cls.shipment2 = Purchase.objects.create(
         tag=8, 
         shipment_id=8888, 
         supplier_id=cls.supplier1, 
         purchase_date='2015-01-08', 
         purchase_price=8.88, 
         product_name=cls.variety1, 
         pieces=88, 
         kgs=888, 
         crackout_estimate=88.8 
         ) 
    cls.shipment3 = Purchase.objects.create(
         tag=7, 
         shipment_id=7777, 
         supplier_id=cls.supplier1, 
         purchase_date='2014-01-07', 
         purchase_price=7.77, 
         product_name=cls.variety1, 
         pieces=77, 
         kgs=777, 
         crackout_estimate=77.7 
         ) 

    cls.sortrecord1 = SortingRecords.objects.create(
         tag=cls.shipment1, 
         date="2015-02-05", 
         bags_sorted=20, 
         turnout=199, 
         ) 

    cls.sortrecord2 = SortingRecords.objects.create(
         tag=cls.shipment1, 
         date="2015-02-07", 
         bags_sorted=40, 
         turnout=399, 
         ) 
    cls.sortrecord3 = SortingRecords.objects.create(
         tag=cls.shipment1, 
         date='2015-02-09', 
         bags_sorted=30, 
         turnout=299, 
         ) 

मॉडल

from datetime import datetime 

from django.db import models 
from django.db.models import Q 


class ProductGroup(models.Model): 
    product_name = models.CharField(max_length=140, primary_key=True) 

    def __str__(self): 
     return self.product_name 

    class Meta: 
     verbose_name = "Product" 

class Supplier(models.Model): 
    company_name = models.CharField(max_length=45) 
    company_location = models.CharField(max_length=45) 
    contact_info = models.CharField(max_length=256) 

    class Meta: 
     ordering = ["company_name"] 

    def __str__(self): 
     return self.company_name 

class Variety(models.Model): 
    product_group = models.ForeignKey(ProductGroup) 
    variety_name = models.CharField(max_length=140) 
    husked = models.BooleanField() 
    finished = models.BooleanField() 
    description = models.CharField(max_length=500, blank=True) 

    class Meta: 
     ordering = ["product_group_id"] 
     verbose_name_plural = "Varieties" 

    def __str__(self): 
     return self.variety_name 


class PurchaseYears(models.Manager): 

    def purchase_years_list(self): 
     unique_years = Purchase.objects.dates('purchase_date', 'year') 
     results_list = [] 
     for p in unique_years: 
      results_list.append(p.year) 
     return results_list 


class Purchase(models.Model): 
    tag = models.IntegerField(primary_key=True) 
    product_name = models.ForeignKey(Variety, related_name='purchases') 
    shipment_id = models.CharField(max_length=24) 
    supplier_id = models.ForeignKey(Supplier) 
    purchase_date = models.DateField() 
    estimated_delivery = models.DateField(null=True, blank=True) 
    purchase_price = models.DecimalField(max_digits=6, decimal_places=3) 
    pieces = models.IntegerField() 
    kgs = models.IntegerField() 
    crackout_estimate = models.DecimalField(max_digits=6,decimal_places=3, null=True) 
    crackout_actual = models.DecimalField(max_digits=6,decimal_places=3, null=True) 
    objects = models.Manager() 
    purchase_years = PurchaseYears() 
    # Keep manager as "objects" in case admin, etc. needs it. Filter can be called like so: 
    # Purchase.objects.purchase_years_list() 
    # Managers in docs: https://docs.djangoproject.com/en/1.8/intro/tutorial01/ 

    class Meta: 
     ordering = ["purchase_date"] 

    def __str__(self): 
     return self.shipment_id 

    def _weight_conversion(self): 
     return round(self.kgs * 2.20462) 
    lbs = property(_weight_conversion) 

class SortingModelsBagsCalulator(models.Manager): 

    def total_sorted(self, record_date, current_set): 
     sorted = [SortingRecords['bags_sorted'] for SortingRecords in current_set if 
        SortingRecords['date'] <= record_date] 
     return sum(sorted) 


class SortingRecords(models.Model): 
    tag = models.ForeignKey(Purchase, related_name='sorting_record') 
    date = models.DateField() 
    bags_sorted = models.IntegerField() 
    turnout = models.IntegerField() 
    objects = models.Manager() 

    def __str__(self): 
     return "%s [%s]" % (self.date, self.tag.tag) 

    class Meta: 
     ordering = ["date"] 
     verbose_name_plural = "Sorting Records" 

    def _calculate_kgs_sorted(self): 
     kg_per_bag = self.tag.kgs/self.tag.pieces 
     kgs_sorted = kg_per_bag * self.bags_sorted 
     return (round(kgs_sorted, 2)) 
    kgs_sorted = property(_calculate_kgs_sorted) 

    def _byproduct(self): 
     waste = self.kgs_sorted - self.turnout 
     return (round(waste, 2)) 
    byproduct = property(_byproduct) 

    def _bags_remaining(self): 
     current_set = SortingRecords.objects.values().filter(~Q(id=self.id), tag=self.tag) 
     sorted = [SortingRecords['bags_sorted'] for SortingRecords in current_set if 
        SortingRecords['date'] <= self.date] 
     remaining = self.tag.pieces - sum(sorted) - self.bags_sorted 
     return remaining 
    bags_remaining = property(_bags_remaining) 

संपादित

यह भी पूर्णांकों के साथ विफल रहता है तो तरह।

django.db.utils.IntegrityError: duplicate key value violates unique constraint "InventoryLogs_purchase_pkey" 
DETAIL: Key (tag)=(9) already exists. 

अपडेट करें

तो मैं इस पहले उल्लेख किया जाना चाहिए था, लेकिन मैं पूरी तरह से भूल गया था। मेरे पास दो यूनिट परीक्षण फ़ाइलें हैं जो समान डेटा का उपयोग करती हैं। सिर्फ किक्स के लिए, मैंने setUpTestData() के दोनों उदाहरणों में एक अलग मूल्य से प्राथमिक कुंजी मिलान की और निश्चित रूप से पर्याप्त, मुझे एक ही त्रुटि मिली।

इनमें से एक में अधिक डेटा जोड़ने से पहले ये दो सेटअप ठीक से काम कर रहे थे। अब, ऐसा प्रतीत होता है कि उन्हें विभिन्न मूल्यों की आवश्यकता है। मुझे लगता है कि आप केवल इतने लंबे समय तक दोहराए गए डेटा का उपयोग कर दूर हो सकते हैं।

+1

तुम क्यों न दें db आईडी चुना? –

+0

आपको अपने मॉडल को अपनी पोस्ट में रखना चाहिए। क्या यह संभव है कि 'SortingRecords.tag' अद्वितीय होना चाहिए? –

+0

हां। वह शायद बुद्धिमान होगा। मुझे लगता है कि मैंने इसे शुरुआत में इस तरह से स्थापित किया क्योंकि मैं कई टैग, उत्पादों, आदि की घटना को रोकना चाहता था .. उस समय यह सबसे स्पष्ट तरीका था, लेकिन मुझे यकीन है कि ऐसा करने का एक शानदार तरीका है। –

उत्तर

0

सभी अपने परीक्षण डाटा स्ट्रिंग उपसर्ग चाहिए के रूप में प्रश्न के तल पर ध्यान दिया मैं, इस मुद्दे की खोज की ऐसी त्रुटियों को रोकने के लिए।

जो मैं कह सकता हूं, डेटाबेस ने दो अलग-अलग परीक्षणों के setUpTestData() विधियों में डुप्लिकेट डेटा का उपयोग करके मुझे पसंद नहीं किया। दूसरे परीक्षण में प्राथमिक कुंजी मानों को बदलने से समस्या ठीक हुई।

0

आपके द्वारा प्रदान किया गया लॉग DETAIL: Key (product_name)=(Almonds) already exists बताता है। क्या आपने अपने डीबी में सत्यापित किया था?

भविष्य में, आप द्वारा test_

+0

असल में, बादाम उत्पाद के नाम के रूप में मौजूद हैं और थोड़ी देर के लिए हैं। हालांकि, यह पहले कभी एक मुद्दा नहीं था। टेस्टकेस के तहत परीक्षण हमेशा सफलतापूर्वक चलाने में सक्षम थे। इसके अलावा, यह मुझे टैग के लिए एक ही त्रुटि देता है, जो डेटाबेस में डुप्लीकेट नहीं होते हैं, लेकिन प्रत्येक परीक्षण के साथ बनाए गए (माना जाता है) हैं, फिर हटा दिए जाते हैं। मुझे फिर से पुन: प्रयास करना चाहिए, यह रहस्यमय डेटा वास्तव में परीक्षण के दौरान खुद को पेश नहीं करता है। –

+0

क्या आपने हाल ही में 'manage.py माइग्रेट' का उपयोग किया था? मुझे लगता है कि यह डीबी का एक स्नैपशॉट बनाता है जिसे प्रयोग –

+0

परीक्षणों के शुरुआती बिंदु के रूप में उपयोग किया जाता है हां, मैंने वास्तव में माइग्रेशन को बहुत खराब कर दिया था, इसलिए मैंने काम का एक गुच्छा उलट दिया। जाहिर है कि इस प्रयास ने इस मुद्दे को ठीक नहीं किया था। वैसे भी, मैं आपके लिए एक त्रुटि फिर से बनाने की कोशिश कर रहा था, लेकिन यह मुद्दा दूर चला गया प्रतीत होता है। मेरे पास अपवॉट करने के लिए पर्याप्त प्रतिनिधि नहीं है, लेकिन आपकी मदद के लिए धन्यवाद। –

0

मुझे लगता है कि यहां समस्या यह है कि आपके टेस्टकेस में सुपर विधि के कॉल के बिना आपके पास टियरडाउन क्लास विधि थी। इस तरह से django टेस्टकेस ने SetUpTestData के पीछे लेनदेन संबंधी कार्यक्षमताओं को खो दिया है, इसलिए यह टेस्टकेस समाप्त होने के बाद आपके परीक्षण डीबी को साफ़ नहीं करता है। Django डॉक्स यहाँ

चेक चेतावनी: https://docs.djangoproject.com/en/1.10/topics/testing/tools/#django.test.SimpleTestCase.allow_database_queries

संबंधित मुद्दे