2011-09-07 10 views
16

पर एक विदेशी के संबंध बदलें मैं अपने Django ऐप के साथ दक्षिण का उपयोग कर रहा हूँ। मेरे पास दो मॉडल हैं जिन्हें मैं संबंध OneToOneField संबंध रखने के संबंध में बदल रहा हूं। जब मैंने अपने देव डेटाबेस पर यह माइग्रेशन चलाया, तो यह ठीक हो गया। जब परीक्षण डेटाबेस बनाने के हिस्से के रूप में माइग्रेशन चलाया जाता है, तो नवीनतम माइग्रेशन एक MySQL 1005 त्रुटि के साथ विफल रहता है: "तालिका mydb नहीं बना सकता। # Sql-3249_1d (errno: 121)"। कुछ गूगलिंग करने से पता चला कि यह आमतौर पर मौजूदा बाधा के समान नाम के साथ बाधा जोड़ने की कोशिश करने में एक समस्या है। प्रवास में विशिष्ट लाइन है कि उस पर विफल रहता है:Django - OneToOne

db.alter_column('myapp_mymodel', 'othermodel_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['myapp.OtherModel'], unique=True)) 

db.create_unique('myapp_mymodel', ['othermodel_id']) 
:

class MyModel(models.Model): 
    othermodel = models.ForeignKey(OtherModel) 

class MyModel(models.Model): 
    othermodel = models.OneToOneField(OtherModel) 

जो प्रवास में निम्नलिखित बयानों उत्पन्न करने के लिए:

संबंध से बदल गया था

लेकिन create_unique कॉल पर असफल होने की बजाय, यह 01 पर विफल रहा हैकॉल करें। मैं निम्न आदेश दौड़ा देखने के लिए एसक्यूएल उत्पन्न किया जा रहा था:

python manage.py migrate myapp 0010 --db-dry-run --verbosity=2 

और यह

myapp:0010_auto__chg_field_mymodel_othermodel__add_unique_mymodel 
    = ALTER TABLE `myapp_mymodel` ADD CONSTRAINT `myapp_mymodel_othermodel_id_uniq` UNIQUE (`othermodel_id`) [] 
    = SET FOREIGN_KEY_CHECKS=1; [] 
    = ALTER TABLE `myapp_mymodel` ADD CONSTRAINT `myapp_mymodel_othermodel_id_uniq` UNIQUE (`othermodel_id`) [] 

यह अजीब है कि यह ADD CONSTRAINT दो बार चलाने के लिए कोशिश कर रहा है लगता है मुद्रित लेकिन अगर मैं db.create_unique को दूर कॉल करें, जब मैं इसे --db-dry-run के साथ चलाता हूं तो कोई एसक्यूएल उत्पन्न नहीं होता है, लेकिन अगर मैं इसे वास्तविक के लिए चलाता हूं तो मुझे अभी भी त्रुटि मिलती है।

मैं यहां एक नुकसान में हूं, किसी भी मदद की सराहना की जाती है।

+1

मैं बिल्कुल वैसा ही माइग्रेशन बनाया है कुछ दिन पहले और यह ठीक भाग गया। क्या आप एक ही डेटाबेस को एक अलग डेटाबेस बैकएंड के साथ आज़मा सकते हैं (मैंने इसे PostgreSQL डेटाबेस पर किया था)। इसके अलावा, अपने दक्षिण संस्करण की जांच करें। – emyller

+0

इच्छा है कि मैं मदद कर सकता हूं - मैंने परिवर्तन किया है, यह एक ही पायथन और एसक्यूएल कोड उत्पन्न करता है, और माइग्रेशन Win32 के लिए mysql 5.1.56 का उपयोग करके ठीक है। – Hannele

+0

इसे दक्षिण मेलिंग सूची पर पूछें और आपको उत्तर खोजने की संभावना है। –

उत्तर

0

पहली चीज जो मैं कोशिश करूंगा, यह देखने के लिए कि मैं इसे हैक कर सकता हूं, विभिन्न स्थानों पर db.delete_unique(...) जोड़ना होगा।

उसमें असफल होने पर मैं इसे विभाजित था 3 माइग्रेशन में:

  1. एक स्कीमा प्रवास करने से अधिक पुरानी स्तंभ से सब FK मूल्यों कॉपी करने के लिए एक डेटा प्रवास OneToOne
  2. के लिए एक नया स्तंभ जोड़ने के लिए नया
  3. पुराने कॉलम को हटाने के लिए एक स्कीमा माइग्रेशन, जिसे मैं पुराने कॉलम का नाम बदलने के लिए मैन्युअल रूप से संपादित करने के लिए मैन्युअल रूप से संपादित करता हूं।
11

आपको वास्तव में माइग्रेशन की आवश्यकता नहीं है। OneToOne और ForeignKey रिश्तों में हुक के नीचे एक संगत डेटाबेस स्कीमा है: तालिका में से किसी एक में अन्य ऑब्जेक्ट आईडी वाला एक साधारण कॉलम।

यदि आप इस परिवर्तन को अनदेखा करने के लिए दक्षिण को बताने की परेशानी में प्रवेश नहीं करना चाहते हैं तो बस migrate --fake के साथ माइग्रेशन को नकली करें।

+0

और यदि आपको संदेह है कि @ ई-सैटिस इस बारे में सही है, तो इस बोली को कोड ('django.db.models.fields.related') से लें:" एक OneToOneField अनिवार्य रूप से एक विदेशी के समान है , अपवाद के साथ हमेशा इसके साथ 'अद्वितीय' बाधा होती है "और ध्यान दें कि OneToOne वास्तव में केवल कुछ मामूली tweaks के साथ ForeignKey से विरासत में मिलता है। – mlissner

+0

सटीक होने के लिए, विदेशीकी से OneToOneField के क्षेत्र को बदलने से डेटाबेस पर प्रभाव पड़ता है (कम से कम उन सहायक बाधाओं पर), जिन्हें छोड़ा नहीं जाना चाहिए: एक विदेशीकी अद्वितीय नहीं है, जबकि OneToOneField है। Django 1.8 में - mysql बैकएंड पर देशी कमांड 'makemigrations' का उपयोग कर - मुझे कोई समस्या नहीं थी। माइग्रेशन ने डीबी स्तर पर क्षेत्र पर पिछले गैर-अद्वितीय इंडेक्स को सही ढंग से हटा दिया, और नई अनूठी अनुक्रमणिका सेट की। – baxeico

1

मैं @ ई-सैटिस से सहमत हूं कि यहां लक्ष्य लक्ष्य को नकली करना है, लेकिन यदि आप एक टीम के साथ काम कर रहे हैं तो मैं एक अलग दृष्टिकोण सुझाता हूं।

यदि आप माइग्रेशन बनाते हैं तो --fake इसे, आपके सभी टीम सदस्यों को --fake भी याद रखना होगा। यदि उनमें से कोई भी अपग्रेड करते समय ऐसा नहीं करता है, तो आप परेशानी में हैं।

एक बेहतर दृष्टिकोण एक खाली प्रवास बनाने के लिए है, तो यह विस्थापित:

manage.py schemamigration yourapp --empty fake_migration_of_foreign_key_to_onetoone 
manage.py migrate # Like you always do! 
संबंधित मुद्दे