2011-11-24 14 views
8

को मॉडल मैं तीन क्षेत्रोंमाइग्रेट Django unique_together बाधा

class MyModel(models.Model): 
    a = models.ForeignKey(A) 
    b = models.ForeignKey(B) 
    c = models.ForeignKey(C) 

मैं इन क्षेत्रों के बीच एक अद्वितीय बाधा लागू करना चाहते हैं के साथ एक मॉडल है, और पाया Django के unique_together, जो समाधान हो रहा है। हालांकि, मेरे पास पहले से मौजूद एक मौजूदा डेटाबेस है, और कई डुप्लिकेट हैं। मुझे पता है कि unique_together डेटाबेस स्तर पर काम करता है, इसलिए मुझे पंक्तियों को अद्वितीय-ify की आवश्यकता है, और फिर माइग्रेशन आज़माएं।

डुप्लिकेट को हटाने के बारे में जाने का कोई अच्छा तरीका है (जहां एक डुप्लिकेट समान है (ए, बी, सी)) ताकि मैं unique_together contstraint प्राप्त करने के लिए माइग्रेशन चला सकूं?

+0

आप अपने मॉडल पर किसी भी अन्य क्षेत्रों की क्या ज़रूरत है (कि प्रभावित कर सकता है है रखने के लिए डुप्लिकेट की पसंद)? – second

+0

मेरे पास एक create_at समय है जो शायद सबसे अच्छा संकेतक होगा – jkeesh

उत्तर

22

यदि आप मनमाने ढंग से डुप्लिकेट में से किसी एक को चुनने में प्रसन्न हैं, तो मुझे लगता है कि निम्नलिखित चाल चल सकती है। शायद सबसे कुशल लेकिन सरल नहीं है और मुझे लगता है कि आपको केवल एक बार इसे चलाने की आवश्यकता है। अगर आप कुछ मूर्खतापूर्ण तरीके से कर चुके हैं, तो कृपया यह सब कुछ परीक्षण डेटा पर स्वयं को सत्यापित करें, क्योंकि आप डेटा का एक समूह हटाना चाहते हैं।

सबसे पहले हमें ऑब्जेक्ट्स के समूह मिलते हैं जो डुप्लिकेट बनाते हैं। प्रत्येक समूह के लिए, (मनमाने ढंग से) एक "मास्टर" चुनें जिसे हम रखने जा रहे हैं। हमारे चुने हुए विधि सबसे कम pk

master_pks = MyModel.objects.values('A', 'B', 'C' 
    ).annotate(Min('pk'), count=Count('pk') 
    ).filter(count__gt=1 
    ).values_list('pk__min', flat=True) 

हम तो प्रत्येक गुरु से अधिक पाश के साथ एक अपने सभी डुप्लिकेट चुनें, और नष्ट करने के लिए

masters = MyModel.objects.in_bulk(list(master_pks)) 

for master in masters.values(): 
    MyModel.objects.filter(a=master.a, b=master.b, c=master.c 
     ).exclude(pk=master.pk).del_ACCIDENT_PREVENTION_ete() 
+1

क्या हम माइग्रेशन फ़ाइल में ऐसा कुछ कर सकते हैं जो अतिरिक्त स्क्रिप्ट चलाने से बचें? – chhantyal

+1

'.del_ACCIDENT_PREVENTION_elte()' क्या है? – Dusty

+7

'ACCIDENT_PREVENTION' वाक्यांश के साथ 'हटाएं' लोगों को गलती से कोड को प्रतिलिपि/चिपकाने के बिना कोड को मिटाने से रोकने के लिए मध्य में जोड़ा गया – second

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