python - मॉडल और रिलेशनशिप फ़ील्ड का नाम बदलने के लिए Django माइग्रेशन रणनीति




django-migrations (6)

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

आइए मान लें कि myapp नामक एक Django ऐप के भीतर मैं निम्नलिखित मॉडलों के साथ शुरू करता हूं:

class Foo(models.Model):
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)


class AnotherModel(models.Model):
    foo = models.ForeignKey(Foo)
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    foo = models.ForeignKey(Foo)
    is_ridonkulous = models.BooleanField()

मैं Foo मॉडल का नाम बदलना चाहता हूं क्योंकि नाम वास्तव में समझ में नहीं आता है और कोड में भ्रम पैदा कर रहा है, और Bar एक बहुत स्पष्ट नाम के लिए तैयार होगा।

Django विकास प्रलेखन में मैंने जो पढ़ा है, उससे मैं निम्नलिखित माइग्रेशन रणनीति मान रहा हूं:

चरण 1

models.py संशोधित करें:

class Bar(models.Model):  # <-- changed model name
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)


class AnotherModel(models.Model):
    foo = models.ForeignKey(Bar)  # <-- changed relation, but not field name
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    foo = models.ForeignKey(Bar)  # <-- changed relation, but not field name
    is_ridonkulous = models.BooleanField()

ध्यान दें कि foo लिए अन्य AnotherModel फ़ील्ड नाम बदल नहीं है, लेकिन संबंध Bar मॉडल में अपडेट किया गया है। मेरा तर्क यह है कि मुझे एक बार में बहुत ज्यादा बदलाव नहीं करना चाहिए और यदि मैंने इस क्षेत्र का नाम bar बदल दिया है तो मुझे उस कॉलम में डेटा खोने का जोखिम होगा।

चरण 2

एक खाली माइग्रेशन बनाएं:

python manage.py makemigrations --empty myapp

चरण 3

संचालन सूची में RenameModel ऑपरेशन जोड़ने के लिए चरण 2 में बनाई गई माइग्रेशन फ़ाइल में Migration क्लास को संपादित करें:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.RenameModel('Foo', 'Bar')
    ]

चरण 4

माइग्रेशन लागू करें:

python manage.py migrate

चरण 5

models.py में संबंधित फ़ील्ड नाम संपादित करें:

class Bar(models.Model):
    name = models.CharField(unique=True, max_length=32)
    description = models.TextField(null=True, blank=True)


class AnotherModel(models.Model):
    bar = models.ForeignKey(Bar)  # <-- changed field name
    is_awesome = models.BooleanField()


class YetAnotherModel(models.Model):
    bar = models.ForeignKey(Bar)  # <-- changed field name
    is_ridonkulous = models.BooleanField()

चरण 6

एक और खाली माइग्रेशन बनाएं:

python manage.py makemigrations --empty myapp

चरण 7

संचालन सूची में किसी भी संबंधित फ़ील्ड नामों के लिए RenameField ऑपरेशन जोड़ने के लिए चरण 6 में बनाई गई माइग्रेशन फ़ाइल में Migration क्लास संपादित करें:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0002_rename_fields'),  # <-- is this okay?
    ]

    operations = [
        migrations.RenameField('AnotherModel', 'foo', 'bar'),
        migrations.RenameField('YetAnotherModel', 'foo', 'bar')
    ]

चरण 8

दूसरा प्रवास लागू करें:

python manage.py migrate

नए चर नामों को प्रतिबिंबित करने के लिए शेष कोड (विचार, रूप, आदि) को अपडेट करने के अलावा, क्या यह मूल रूप से नई माइग्रेशन कार्यक्षमता कैसे काम करेगी?

इसके अलावा, यह बहुत सारे कदमों की तरह लगता है। क्या प्रवासन परिचालन किसी तरह से घुलनशील हो सकता है?

धन्यवाद!


Django 1.10 के लिए, मैं बस मैकेमिग्रेशंस चलाकर दो मॉडल वर्ग के नाम (एक विदेशी कुंजी सहित, और डेटा के साथ) को बदलने में कामयाब रहा, और फिर ऐप के लिए माइग्रेट कर दिया। Makemigrations कदम के लिए, मुझे पुष्टि करनी थी कि मैं टेबल नाम बदलना चाहता था। माइग्रेट ने बिना किसी समस्या के तालिकाओं के नाम बदल दिए।

तब मैंने विदेशीकी क्षेत्र का नाम मिलान करने के लिए बदल दिया, और फिर से यह पुष्टि करने के लिए माकमेग्रेशन द्वारा पूछा गया कि मैं नाम बदलना चाहता हूं। परिवर्तन करने से माइग्रेट करें।

इसलिए मैंने इसे बिना किसी विशेष फ़ाइल संपादन के दो चरणों में लिया। मुझे पहली बार त्रुटियां मिलीं क्योंकि मैं @ wasibigeek द्वारा उल्लिखित admin.py फ़ाइल को बदलना भूल गया था।


तो जब मैंने यह कोशिश की, ऐसा लगता है कि आप चरण 3 - 7 को संयोजित कर सकते हैं:

class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'), 
    ]

    operations = [
        migrations.RenameModel('Foo', 'Bar'),
        migrations.RenameField('AnotherModel', 'foo', 'bar'),
        migrations.RenameField('YetAnotherModel', 'foo', 'bar')
    ]

यदि आप नामों को अपडेट नहीं करते हैं, तो आपको कुछ त्रुटियां मिल सकती हैं जैसे admin.py और यहां तक ​​कि पुरानी माइग्रेशन फ़ाइलें (!)।

अद्यतन : जैसा कि ceasaro का उल्लेख है, डीजेंगो के नए संस्करण आमतौर पर पता लगाने और पूछने में सक्षम होते हैं कि मॉडल का नाम बदल दिया गया है या नहीं। तो पहले manage.py makemigrations और फिर माइग्रेशन फ़ाइल की जांच करें।


मुझे एक ही काम करने की ज़रूरत थी। मैंने मॉडल को एक बार में बदल दिया (यानी, चरण 1 और चरण 5 एक साथ)। फिर एक स्कीमा माइग्रेशन बनाया लेकिन इसे यह संपादित करने के लिए संपादित किया:

class Migration(SchemaMigration):
    def forwards(self, orm):
        db.rename_table('Foo','Bar')

    def backwards(self, orm):
        db.rename_table('Bar','Foo')

यह पूरी तरह से काम किया। मेरे सभी मौजूदा डेटा दिखाए गए, अन्य सभी तालिकाओं को बार ठीक संदर्भित किया गया।

यहां से: https://hanmir.wordpress.com/2012/08/30/rename-model-django-south-migration/


मुझे दो टेबलों का नाम बदलने की जरूरत थी। लेकिन Django द्वारा केवल एक मॉडल नाम देखा गया था। ऐसा इसलिए हुआ क्योंकि Django जोड़े गए, फिर मॉडल हटा दिया। प्रत्येक जोड़ी के लिए यह जांचता है कि क्या वे एक ही ऐप के हैं और समान फ़ील्ड हैं । नामों का नाम बदलने के लिए केवल एक तालिका में कोई विदेशी कुंजी नहीं थी (विदेशी कुंजी में मॉडल श्रेणी का नाम होता है, जैसा आपको याद है)। दूसरे शब्दों में, केवल एक तालिका में कोई फ़ील्ड परिवर्तन नहीं था। यही कारण है कि यह देखा गया था।

तो, समाधान एक समय में एक टेबल का नाम बदलना, models.py में मॉडल वर्ग का नाम बदलना, संभवतः views.py , और माइग्रेशन करना है। इसके बाद अन्य संदर्भों के लिए अपना कोड (मॉडल श्रेणी के नाम, संबंधित (क्वेरी) नाम, परिवर्तनीय नाम) का निरीक्षण करें। यदि आवश्यक हो, तो माइग्रेशन करें। फिर, वैकल्पिक रूप से इन सभी माइग्रेशन को एक में संयोजित करें (आयात को प्रतिलिपि बनाना सुनिश्चित करें)।


मैं Django संस्करण 1.9.4 का उपयोग कर रहा हूँ

मैंने निम्नलिखित चरणों का पालन किया है: -

मैंने सिर्फ पुराने नाम को न्यूनाम रन में python manage.py makemigrations नाम बदल दिया है। यह आपको पूछेगा कि Did you rename the appname.oldName model to NewName? [y/N] Did you rename the appname.oldName model to NewName? [y/N] वाई का चयन करें

चलाएं python manage.py migrate और यह आपको पूछेगा

निम्नलिखित सामग्री प्रकार पुराने हैं और हटाए जाने की आवश्यकता है:

appname | oldName
appname | NewName

इन सामग्री प्रकारों से संबंधित किसी भी वस्तु को विदेशी कुंजी द्वारा हटा दिया जाएगा। क्या आप वाकई इन सामग्री प्रकारों को मिटाना चाहते हैं? यदि आप अनिश्चित हैं, तो जवाब 'नहीं'।

Type 'yes' to continue, or 'no' to cancel: Select No

यह सभी मौजूदा डेटा का नाम बदलकर नए नामांकित टेबल पर माइग्रेट कर देता है।


मैंने संस्करण 10 से संस्करण 11 तक Django को अपग्रेड किया:

sudo pip install -U Django

( -U "अपग्रेड" के लिए) और यह समस्या हल हो गई।





django-migrations