2012-04-03 19 views
8

सेट नहीं करता है, मैं अपने django मॉडल माइग्रेट करने के लिए दक्षिण का उपयोग करता हूं। हालांकि दक्षिण में एक बुरा बग है। यह Postgres डेटाबेस में डिफ़ॉल्ट मान सेट नहीं करता है। उदाहरण:django दक्षिण माइग्रेशन, डिफ़ॉल्ट

created_at = models.DateTimeField(default = datetime.now) 
tag_id = models.PositiveIntegerField(default = 0) 

दक्षिण डेटाबेस के लिए इन 2 क्षेत्रों जोड़ना होगा, लेकिन उनके डिफ़ॉल्ट मानों, जो मैन्युअल रूप से किया जाना चाहिए निर्धारित करने के लिए असफल।

क्या इस बग के लिए कोई पैच है?

अद्यतन मैं पहले से ही auto_now_add=True के साथ डिफ़ॉल्ट तिथि सेट करने की कोशिश की थी, लेकिन वह भी डिफ़ॉल्ट सेट नहीं है। क्षेत्र में null=True जोड़कर दक्षिण द्वारा उत्पादित माइग्रेशन स्क्रिप्ट में db.alter_column जोड़ता है। लेकिन केवल NOT NULL बाधा को हटा देता है, डिफ़ॉल्ट नहीं जोड़ता है। पूर्णांक फ़ील्ड के लिए समान

उत्तर

11

यह दक्षिण या अन्य जगहों पर एक बग नहीं है।

मुझे लगता है कि आप उलझन में हैं कि आम तौर पर Django में डिफ़ॉल्ट मान कैसे काम करते हैं। Django डेटाबेस स्कीमा में डिफ़ॉल्ट मान सेट नहीं करता है। जब यह एक नया उदाहरण बनाया जाता है, तो यह उन्हें सीधे पायथन में लागू करता है। आप इसे manage.py sqlall करके सत्यापित कर सकते हैं और देख सकते हैं कि जेनरेट किए गए SQL में default विशेषताएँ नहीं हैं।

+2

मैं पोस्टग्रेज़ डेटाबेस में डिफ़ॉल्ट कैसे लागू कर सकता हूं। मेरे पास apis है जो django द्वारा बनाए गए डेटाबेस के साथ सीधे बातचीत करता है। वे डिफ़ॉल्ट रूप से होने की उम्मीद करते हैं। – jerrymouse

+5

आपको स्वयं स्कीमा को संशोधित करने के लिए कस्टम एसक्यूएल का उपयोग करना होगा। आप एसक्यूएल को ['db.execute'] (http://south.aeracode.org/docs/databaseapi.html#db-execute) में पास करके दक्षिण में ऐसा कर सकते हैं। –

+3

डैनियल सिर्फ इसलिए कि Django उपयोगकर्ताओं को स्कीमा स्तर पर फ़ील्ड डिफ़ॉल्ट को बदलने से रोकने की कोशिश करता है, इसका मतलब यह नहीं है कि उन्हें सक्षम नहीं होना चाहिए। मैंने नीचे एक वास्तविक समाधान पोस्ट किया है। – galarant

21

आप अपने माइग्रेशन का उपयोग कर स्वचालित रूप जेनरेट कर रहे हैं:

./manage.py schemamigration app_name --auto 

तो फिर तुम प्रवास करने के लिए एक छोटा सा संपादित करने के लिए इससे पहले कि आप वास्तव में इसे लागू की जरूरत है। उत्पन्न प्रवास में जाएं (app_name/माइग्रेशन/000X__auto_add_field_foo.py की तरह कुछ कहा जाना चाहिए) और तर्क के लिए देखो: db.add_column कॉल में

keep_default=False 

। सीधे शब्दों में यह बदलने के लिए:

keep_default=True 

और Django अब अपनी डिफ़ॉल्ट मान वास्तविक स्कीमा के अलावा किसी भी मौजूदा पंक्तियों पर लागू होगा। अच्छा होगा अगर दक्षिण में इस पैरामीटर को डिफ़ॉल्ट रूप से सही के रूप में उत्पन्न करने के लिए किसी प्रकार की सेटिंग थी, लेकिन ऐसी कोई किस्मत नहीं थी। आपको हर बार यह संपादन करने की आवश्यकता होगी।

+0

+1 कस्टम एसक्यूएल –

+5

+1 लिखने से कहीं अधिक आसान है। दुर्भाग्यवश ['keep_default' को दक्षिण 0.8.1 में बहिष्कृत किया गया है] (http://south.readthedocs.org/en/latest/releasenotes/0.8.1.html#keep-default-fully-deprecated) – Pankrat

+0

लानत, पंकत सही है ... – galarant

2

जैसा कि पहले के उत्तरों में बताया गया है, डीजेंगो में डिफ़ॉल्ट तंत्र मॉडल वर्ग में लागू किया गया है, और यह दक्षिण माइग्रेशन के लिए प्रासंगिक नहीं है।

इसके अलावा, दक्षिण 0.8, the keep_default flag is deprecated से, और आपके मॉडल में डिफ़ॉल्ट मान नहीं जोड़ देगा।

मैं इसे हल करने के लिए क्या करता हूं डिफ़ॉल्ट मान जोड़ने के लिए एक कस्टम माइग्रेशन लिख रहा है। आप एक अलग data migration बनाकर ऐसा कर सकते हैं:

./manage.py datamigration your_app_name migration_name 

और forwards समारोह में निम्नलिखित पंक्ति जोड़:

orm.YourModel.objects.update(field_name = DEFAULT_VALUE) 

वैकल्पिक रूप से, बजाय एक नया माइग्रेशन बनाने के बजाय, आप अपने मूल प्रवास को संशोधित कर सकते हैं:

  1. कक्षा में no_dry_run = True जोड़ें (इसलिए आपको ORM तक पहुंच होगी)।
  2. forwards फ़ंक्शन के अंत में जोड़ें।

इस तरह आपको पीछे की ओर माइग्रेशन लिखना नहीं है, क्योंकि आपके पास पहले से ही मूल डिलीट-कॉलम है।

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