استراتيجية الهجرة جانغو لإعادة تسمية نموذج ومجالات العلاقة

StackOverflow https://stackoverflow.com//questions/25091130

سؤال

أنا أخطط لإعادة تسمية عدة نماذج في مشروع جانغو القائمة حيث هناك العديد من النماذج الأخرى التي لديها علاقات المفتاح الخارجي للنماذج وأود أن إعادة تسمية.أنا متأكد إلى حد ما من أن هذا سيتطلب عمليات ترحيل متعددة ، لكنني لست متأكدا من الإجراء الدقيق.

دعونا نقول أبدأ مع النماذج التالية داخل التطبيق جانغو دعا myapp:

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 من شأنه أن يجعل لاسم أكثر وضوحا.

من ما قرأت في وثائق التنمية جانغو ، أفترض استراتيجية الهجرة التالية:

الخطوة 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()

لاحظ ال AnotherModel اسم الحقل لـ foo لا يتغير ، ولكن يتم تحديث العلاقة إلى Bar نموذج.منطقي هو أنني لا يجب أن أتغير كثيرا في وقت واحد وأنه إذا غيرت اسم الحقل هذا إلى bar وأود أن خطر فقدان البيانات في هذا العمود.

الخطوة 2

إنشاء ترحيل فارغ:

python manage.py makemigrations --empty myapp

الخطوة 3

تحرير Migration فئة في ملف الترحيل الذي تم إنشاؤه في الخطوة 2 لإضافة RenameModel العملية إلى قائمة العمليات:

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

تحرير Migration فئة في ملف الترحيل الذي تم إنشاؤه في الخطوة 6 لإضافة RenameField العمليات(العمليات) لأي أسماء حقول ذات صلة بقائمة العمليات:

class Migration(migrations.Migration):

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

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

الخطوة 8

تطبيق الهجرة 2:

python manage.py migrate

بصرف النظر عن تحديث بقية التعليمات البرمجية (طرق العرض والنماذج وما إلى ذلك.) لتعكس أسماء المتغيرات الجديدة, هذا هو الأساس كيف وظيفة الهجرة الجديدة ستعمل?

أيضا ، هذا يبدو وكأنه الكثير من الخطوات.هل يمكن تكثيف عمليات الترحيل بطريقة ما?

شكراً!

هل كانت مفيدة؟

المحلول

لذلك عندما جربت هذا ، يبدو أنه يمكنك تكثيف الخطوة 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 وحتى ملفات الترحيل القديمة (!).

تحديث:كما سيزارو يذكر ، إصدارات أحدث من جانغو عادة ما تكون قادرة على الكشف عن ونسأل ما إذا كان يتم إعادة تسمية نموذج.لذا حاول manage.py makemigrations أولا ثم تحقق من ملف الترحيل.

نصائح أخرى

في البداية، اعتقدت أن طريقة Fiver عملت بالنسبة لي لأن الترحيل عملت بشكل جيد حتى الخطوة 4. ومع ذلك، فإن التغييرات الضمنية للتغييرات "FOOOKENT" (FOO) "في" Moverinkeyfieldelield (Bar) "لا ترتبط بأي هجرات. هذا هو السبب في فشل الترحيل عندما أردت إعادة تسمية حقول العلاقة (الخطوة 5-8). قد يكون هذا يرجع إلى حقيقة أن "othermodel" و "Undanothermodel" يتم إرسالها في تطبيقات أخرى في حالتي.

، لذلك تمكنت من إعادة تسمية النماذج الخاصة بي وحقول العلاقة التي تحقق في الخطوات التالية أدناه:

قمت بتكييف الطريقة من هذا وخاصة خدعة أوترانزر.

لذلك مثل fiver دعونا نقول أن لدينا myapp :

giveacodicetagpre.

وفي myotherApp :

giveacodicetagpre.

الخطوة 1:

تحويل كل onetoonefield (foo) أو moviewekyfield (foo) في integerfield (). (سيحتفظ بهذا معرف كائن Foo ذو قيمة Integerfield).

giveacodicetagpre.

ثم

giveacodicetagpre.

الخطوة 2: (مثل الخطوة 2-4 من fiver)

قم بتغيير اسم النموذج

giveacodicetagpre.

قم بإنشاء ترحيل فارغ:

giveacodicetagpre.

ثم تحريرها مثل:

giveacodicetagpre.

في النهاية

giveacodicetagpre.

الخطوة 3:

يحول مرة أخرى إلى InteGerfield الخاص بك () في MoveanKeyfield أو Onetoonefield السابقة ولكن مع نموذج الشريط الجديد. (تم تخزين Integerfield السابق بالمعرف، لذلك فهم Django أنه وإعادة تأسيس الاتصال، وهو بارد.)

giveacodicetagpre.

ثم القيام:

giveacodicetagpre.

من الأهم من ذلك، في هذه الخطوة، يجب عليك تعديل كل هجرة جديدة وإضافة التبعية على هجرات Renamemodel Foo-> Bar. لذلك إذا كانت كل من OtherModel و Leatherothermodel في myotherAbp يجب أن تبدو الترحيل التي تم إنشاؤها في myotherApp مثل هذا:

giveacodicetagpre.

ثم

giveacodicetagpre.

الخطوة 4:

في النهاية يمكنك إعادة تسمية الحقول الخاصة بك

giveacodicetagpre.

ثم قم بإعادة تسمية تلقائية

giveacodicetagpre.

(يجب أن يسألك Django إذا قمت بإعادة تسميته بالفعل اسم الموديل، قل نعم)

giveacodicetagpre.

وهذا هو!

يعمل هذا على django1.8

كنت بحاجة إلى القيام بنفس الشيء.لقد غيرت النموذج مرة واحدة في وقت واحد (I.E.، الخطوة 1 والخطوة 5 معا).ثم أنشأت هجرة مخطط ولكن تحريرها لتكون هذه:

giveacodicetagpre.

هذا عملت تماما.أظهرت جميع بياناتي الحالية، وأشارت جميع الطاولات الأخرى إلى شريط جيد.

من هنا: https:// hanmir.WordPress.com/08/08/30/30/30/30/30/30/30/30/30/30/DEMDEL-DJANGO-SOUTH-MISTRATION/

for django 1.10، تمكنت من تغيير أسماء فئة نموذجيتين (بما في ذلك ورقة أمريكية، ومع البيانات) ببساطة عن طريق تشغيل makemigrations، ثم ترحيل التطبيق.بالنسبة لخطوة ماكيمات الآليات، اضطررت إلى تأكيد أنني أردت تغيير أسماء الطاولة.ترحيل غيرت أسماء الجداول دون مشكلة.

ثم قمت بتغيير اسم حقل FOXTYKEY للمطابقة، ولم يطرحه مرة أخرى من قبل Makemigrations للتأكد من أنني أردت تغيير الاسم.هجر من جعل التغيير.

لذلك أخذت هذا في خطوتين دون أي تحرير ملف خاص.لقد حصلت على أخطاء في البداية لأنني نسيت تغيير ملف ADMIN.PY، كما ذكرنا BySibigekeek.

واجهت أيضا مشكلة V.HOREY الموصوفة ووجدت أن نهجه مفيد للغاية ولكن يمكن تصديقه في خطوات أقل من الخطوة 5 إلى 8 كما هو موضح بدون خطوة 1 إلى 4 باستثناء تلك الخطوة 7 تحتاج إلى أن تكونتغيرت كخطوتي أدناه 3. الخطوات الكلية هي كما تابع:

الخطوة 1: تحرير أسماء الحقول ذات الصلة في Models.py

giveacodicetagpre.

الخطوة 2: إنشاء ترحيل فارغ

giveacodicetagpre.

الخطوة 3: تحرير فئة الترحيل في ملف الترحيل الذي تم إنشاؤه في الخطوة 2

giveacodicetagpre.

الخطوة 4: تطبيق الترحيل

giveacodicetagpre.

تم

p.s.لقد جربت هذا النهج على Django 1.9

أنا باستخدام جانغو الإصدار 1.9.4

لقد اتبع الخطوات التالية:-

لقد قمت للتو بإعادة تسمية النموذج القديم إلى الاسم الجديد تشغيل python manage.py makemigrations.وسوف يطلب منك ل 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

إعادة تسمية وترحيل جميع البيانات الموجودة إلى جدول مسمى جديد بالنسبة لي.

للأسف وجدت مشاكل (كل جانغو 1.x) مع إعادة تسمية الهجرة التي تترك القديم أسماء الجداول في قاعدة البيانات.

جانغو حتى لا يحاول أي شيء على الجدول القديم فقط إعادة تسمية بلده نموذج.نفس المشكلة مع المفاتيح الخارجية والمؤشرات العامة التغييرات هناك لا تتبع بشكل صحيح من قبل جانغو.

أبسط حل (الحل):

class Foo(models.Model):
     name = models.CharField(unique=True, max_length=32)
     ...
Bar = Foo  # and use Bar only

الحل الحقيقي (طريقة سهلة للتبديل جميع مؤشرات, القيود, مشغلات, أسماء, الخ في 2 يرتكب ، بل أصغر الجداول):

ارتكاب:

  1. خلق نفس نموذج القديم
# deprecated - TODO: TO BE REMOVED
class Foo(model.Model):
    ...

class Bar(model.Model):
    ...
  1. تبديل رمز للعمل مع نموذج جديد Bar فقط.(بما في ذلك جميع العلاقات على المخطط)

في الهجرة إعداد RunPython, الذي نسخ البيانات من فو إلى شريط (بما في ذلك id من فو)

  1. اختياري الأمثل (إذا كان هناك حاجة لمزيد من الجداول)

ارتكاب ب: (لا تتعجل ، عندما فريق كامل ترحيل)

  1. آمنة قطرة من النموذج القديم Foo

كذلك تنظيف:

  • الاسكواش على الهجرات

الخلل في جانغو:

كنت بحاجة إلى إعادة تسمية اثنين من الجداول.ولكن لاحظ جانغو إعادة تسمية نموذج واحد فقط.حدث ذلك لأن جانغو يكرر أكثر من المضافة ، ثم إزالة النماذج.لكل زوج يتحقق مما إذا كانوا من نفس التطبيق ولديهم حقول متطابقة.جدول واحد فقط لم يكن لديه مفاتيح خارجية للجداول المراد إعادة تسميتها (تحتوي المفاتيح الخارجية على اسم فئة النموذج ، كما تتذكر).وبعبارة أخرى ، كان جدول واحد فقط أي تغييرات الحقل.لهذا السبب لوحظ.

لذا ، فإن الحل هو إعادة تسمية جدول واحد في كل مرة ، وتغيير اسم فئة النموذج في models.py, ، ربما views.py, ، وجعل الهجرة.بعد ذلك فحص التعليمات البرمجية الخاصة بك لمراجع أخرى (أسماء فئة النموذج ، أسماء (الاستعلام) ذات الصلة ، أسماء المتغيرات).جعل الهجرة ، إذا لزم الأمر.ثم ، اختياريا الجمع بين كل هذه الهجرات في واحد (تأكد من نسخ الواردات كذلك).

وأود أن جعل @كلمات سيزارو ، الألغام على تعليقه على هذا الجواب.

إصدارات أحدث من جانغو يمكن الكشف عن التغييرات ويسأل عن ما تم القيام به.وأود أيضا أن أضيف أن جانغو قد خلط ترتيب تنفيذ بعض أوامر الهجرة.

سيكون من الحكمة تطبيق تغييرات صغيرة وتشغيلها makemigrations و migrate وإذا حدث الخطأ يمكن تحرير ملف الترحيل.

يمكن تغيير بعض خطوط ترتيب التنفيذ لتجنب الأخطاء.

Just wanted to confirm and add upon ceasaro comment. Django 2.0 seems to do this automatically now.

I'm on Jango 2.2.1, all I had to do what to rename the model and run makemigrations.

Here it asks if I had renamed the specific class from A to B, I chose yes and ran migrate and all seems to work.

Note I did not rename the old model name in any files inside the project/migrations folder.

If you are using a good IDE like PyCharm you can right click on the model name and do a refactor -> rename. This saves you the trouble of going through all your code that references the model. Then run makemigrations and migrate. Django 2+ will simply confirm name change.

I upgraded Django from version 10 to version 11:

sudo pip install -U Django

(-U for "upgrade") and it solved the problem.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top