দুটি জ্যাঙ্গো অ্যাপ্লিকেশনের মধ্যে কোনও মডেল কীভাবে স্থানান্তর করবেন (জাজানো 1.7)


133

সুতরাং প্রায় এক বছর আগে আমি একটি প্রকল্প শুরু করেছি এবং সমস্ত নতুন বিকাশকারীদের মতো আমিও কাঠামোর দিকে খুব বেশি মনোনিবেশ করিনি, তবে এখন আমি জাঙ্গোর সাথে আরও উপস্থিত হতে শুরু করেছি যে আমার প্রকল্পের লেআউটটি মূলত আমার মডেলগুলি কাঠামোতে ভয়ঙ্কর are ।

আমার কাছে মডেলগুলি মূলত একটি একক অ্যাপ্লিকেশনটিতে থাকে এবং এই মডেলগুলির বেশিরভাগই তাদের নিজস্ব পৃথক অ্যাপ্লিকেশনগুলিতে হওয়া উচিত, আমি এটি চেষ্টা করে সমাধান করেছি এবং দক্ষিণের সাথে এগুলি সরিয়েছি তবে বিদেশী কী Ect এর কারণে আমি এটিকে জটিল এবং সত্যই কঠিন বলে মনে করেছি।

তবে জাজানো 1.7 এর কারণে এবং মাইগ্রেশনের সমর্থনে নির্মিত এখন এটি করার কী আরও ভাল উপায় আছে?


4
আপনি গ্রহণযোগ্য উত্তর পরিবর্তন বিবেচনা করতে চাইতে পারেন।
বাবকান বর্ধনিয়ান

ভবিষ্যতে লোকেরা এটির জন্য আসবে: এখানে জ্যাঙ্গো ৩.x, এবং রিয়েলপাইথন . com/move-django-model/…বিশদিত পদ্ধতিটি আমার পক্ষে কাজ করেছে। পুরানো অ্যাপ্লিকেশনটির মধ্যে মডেলগুলির মধ্যে আমার কাছে একাধিক বিদেশী কী ছিল এবং নতুন অ্যাপ্লিকেশনটিতে মডেল।
প্রদীপসেপ

উত্তর:


16

আমি পুরানো উত্তরটি সরিয়ে দিচ্ছি ফলে ডেটা ক্ষতি হতে পারে। যেমন ওজান উল্লেখ করেছেন , আমরা প্রতিটি অ্যাপে একটি করে 2 টি মাইগ্রেশন তৈরি করতে পারি। এই পোস্টের নীচে মন্তব্যগুলি আমার পুরানো উত্তর উল্লেখ করে।

প্রথম অ্যাপ্লিকেশন থেকে মডেল সরানোর জন্য প্রথম মাইগ্রেশন।

$ python manage.py makemigrations old_app --empty

এই ক্রিয়াকলাপগুলি অন্তর্ভুক্ত করতে মাইগ্রেশন ফাইল সম্পাদনা করুন।

class Migration(migrations.Migration):

    database_operations = [migrations.AlterModelTable('TheModel', 'newapp_themodel')]

    state_operations = [migrations.DeleteModel('TheModel')]

    operations = [
      migrations.SeparateDatabaseAndState(
        database_operations=database_operations,
        state_operations=state_operations)
    ]

দ্বিতীয় স্থানান্তর যা প্রথম স্থানান্তরের উপর নির্ভর করে এবং ২ য় অ্যাপে নতুন সারণী তৈরি করে। মডেল কোডটি ২ য় অ্যাপে স্থানান্তরিত করার পরে

$ python manage.py makemigrations new_app 

এবং মাইগ্রেশন ফাইলটিকে এ জাতীয় কিছুতে সম্পাদনা করুন।

class Migration(migrations.Migration):

    dependencies = [
        ('old_app', 'above_migration')
    ]

    state_operations = [
        migrations.CreateModel(
            name='TheModel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
            ],
            options={
                'db_table': 'newapp_themodel',
            },
            bases=(models.Model,),
        )
    ]

    operations = [
        migrations.SeparateDatabaseAndState(state_operations=state_operations)
    ]

আমার কাছে বিদ্যমান ডেটা এবং এর অনেকগুলি রয়েছে যা আমি কেবল হারাতে পারি না, এটি সম্ভবত এটি দিয়েই করা যায়?
স্যাম বাকিংহাম

@ কেভিন ক্রিসটফার হেনরি কোডটি পরিবর্তন করেছে। এটি বিদ্যমান ডেটা সংরক্ষণ করে।
চিল্লারনন্দ

@ সামবকিংহাম হ্যাঁ, আপনি ডেটা না হারিয়ে মাইগ্রেট করার জন্য সংশোধিত কোড দিয়ে চেষ্টা করতে পারেন।
চিল্লারনান্দ

2
আমি মনে করি যে এটি সত্যিই সর্বোত্তম উপায় হতে চলেছে, এটি যে দুর্দান্ত সহায়তা করেছে তাদের জন্য আপনাকে ধন্যবাদ।
স্যাম বাকিংহাম

1
আইএমও এটি একটি ভুল সমাধান, মাইগ্রেশনগুলির প্রাথমিক অনুমান হ'ল আপনি চালনা করলে ./manage.py migrateসবকিছু ভাল অবস্থায় শেষ হবে in মাইগ্রেশন ম্যানুয়ালি ফেক করা আইএমও একটি ভুল উপায়।
জেবি।

341

এটি মোটামুটি সহজেই ব্যবহার করে করা যায় migrations.SeparateDatabaseAndState। মূলত, আমরা এক অ্যাপ্লিকেশনটির ইতিহাস থেকে মডেলটি সরাতে এবং অন্যটির মধ্যে তৈরি করতে দুটি স্টেট অপারেশন সহ একই সাথে টেবিলটির নাম পরিবর্তন করতে একটি ডাটাবেস অপারেশন ব্যবহার করি।

পুরানো অ্যাপ্লিকেশন থেকে সরান

python manage.py makemigrations old_app --empty

মাইগ্রেশনে:

class Migration(migrations.Migration):

    dependencies = []

    database_operations = [
        migrations.AlterModelTable('TheModel', 'newapp_themodel')
    ]

    state_operations = [
        migrations.DeleteModel('TheModel')
    ]

    operations = [
        migrations.SeparateDatabaseAndState(
            database_operations=database_operations,
            state_operations=state_operations)
    ]

নতুন অ্যাপে যুক্ত করুন

প্রথমে নতুন অ্যাপের মডেল.পিতে মডেলটি অনুলিপি করুন, তারপরে:

python manage.py makemigrations new_app

এটি CreateModelএকমাত্র অপারেশন হিসাবে একটি নিরীহ অপারেশন সহ মাইগ্রেশন তৈরি করবে । এমন কোনও SeparateDatabaseAndStateঅপারেশনে এমনভাবে মোড়ানো যাতে আমরা টেবিলটি পুনরায় তৈরি করার চেষ্টা করি না। পূর্ববর্তী স্থানান্তরকে নির্ভরতা হিসাবে অন্তর্ভুক্ত করুন:

class Migration(migrations.Migration):

    dependencies = [
        ('old_app', 'above_migration')
    ]

    state_operations = [
        migrations.CreateModel(
            name='TheModel',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
            ],
            options={
                'db_table': 'newapp_themodel',
            },
            bases=(models.Model,),
        )
    ]

    operations = [
        migrations.SeparateDatabaseAndState(state_operations=state_operations)
    ]

14
সত্যিই ভাল ব্যাখ্যা। সারণীর নাম পরিবর্তন করে আপনি কোনও ডেটা হারাতে এড়াতে এই উত্তরটি হওয়া উচিত।
রিমিজ

11
এটি করার সর্বোত্তম উপায় এটি আমার থেকে অনেক ভাল। আমার উত্তরের শীর্ষে নোট যুক্ত করা হয়েছে।
চিল্লারআনন্দ

4
আমি এটি করেছি, কিন্তু যখন আমি এর পরে ন্যাপসটিতে "মেকিমিগ্রেশনস" চালাই, তখন এটি একটির পরিবর্তিত করে একটি অলটারমোডেল টেবিল স্থানান্তর উত্পন্ন করে।
দিয়েগো পনসিয়ানো

4
এই নির্দেশাবলীর ভিত্তিতে আমার সমস্যা সমাধানের একটি উপায় খুঁজে পেয়েছি। আপনার যদি প্রয়োজনীয় ক্ষেত্রগুলি সম্পর্কিত বিদেশী কী উল্লেখ থাকে তবে সমস্যাটি আরও জটিল। রেফারেন্সগুলি সরিয়ে নিতে আমাকে কয়েকটি পদক্ষেপ যুক্ত করতে হয়েছিল।
নস্টালজি.ইও

14
একাধিক অনুরোধের কারণে, আমি একটি গিটহাব উদাহরণ দিয়ে এফকে মডেল মাইগ্রেশন সম্পর্কিত একটি বিশদ উত্তর তৈরি করেছি। stackoverflow.com/questions/30601107/...
Nostalg.io

26

আমিও একই সমস্যার মুখোমুখি হয়েছি। ওজানের উত্তর আমাকে অনেক সাহায্য করেছিল কিন্তু দুর্ভাগ্যক্রমে যথেষ্ট ছিল না। প্রকৃতপক্ষে আমি বেশ কয়েকটি বিদেশীকে মডেলটির সাথে সংযুক্ত করেছিলাম আমি যেতে চেয়েছিলাম। কিছু মাথা ব্যথার পরে আমি সমাধানটি খুঁজে পেয়েছি তাই লোকদের সময় সমাধানের জন্য এটি পোস্ট করার সিদ্ধান্ত নিয়েছি।

আপনার আরও 2 টি পদক্ষেপ দরকার:

  1. কিছু কাজ করার আগে, আপনার সমস্ত পরিবর্তন ForeignKeyলিঙ্ক TheModelমধ্যে Integerfield। তারপরে দৌড়াওpython manage.py makemigrations
  2. ওজানের পদক্ষেপগুলি করার পরে, আপনার বিদেশী কীগুলি পুনরায় রূপান্তর করুন: এর ForeignKey(TheModel)পরিবর্তে পিছনে রাখুন IntegerField()। তারপরে আবার স্থানান্তর করুন ( python manage.py makemigrations)। তারপরে আপনি স্থানান্তর করতে পারেন এবং এটি কাজ করা উচিত ( python manage.py migrate)

আশা করি এটা সাহায্য করবে. অবশ্যই খারাপ উত্সগুলি এড়াতে উত্পাদনের চেষ্টা করার আগে স্থানীয়ভাবে এটি পরীক্ষা করুন :)


8
ম্যান্টিটোমনিফিল্ড সম্পর্ক সম্পর্কে কি ??
টমকনসেল

1
@ টমকাউনসেল দুর্দান্ত মন্তব্য, আমি কেবলমাত্র অভিবাসনের উদ্দেশ্যে মডেলটির মাধ্যমে একটি নির্দিষ্ট যোগ করে ধরে নেব। অটুট তথ্য রেখে যাওয়ার জন্য প্রচুর কাজের দরকার ...
ওয়াটওয়ার

যেহেতু অনেকগুলি থেকে বহু সম্পর্ক সাধারণত দুটি বিদেশী কী সহ কেবল একটি টেবিল, তাই এসকিউএল দৃষ্টিকোণ থেকে আপনি এই উত্তরের কৌশলটি প্রয়োগ করতে পারেন। তবে কেবল জাঙ্গোর মাধ্যমে এটি অর্জন করার জন্য, @Zan উত্তরের পংক্তির সাথে আমি ভাবতে পারি যে প্রথম পদক্ষেপটি এমটিএম সম্পর্কের সাথে জড়িত সারণীগুলির প্রতিলিপি করা (প্রতিটি অ্যাপ্লিকেশনটিতে ডুপের একটি সংস্করণ) থাকবে ate , সমস্ত বিদেশী কীগুলি নতুন অ্যাপ্লিকেশানে স্থানান্তরিত করুন এবং তারপরেই পুরানো অ্যাপ্লিকেশনটির ডুপগুলি মুছুন। দাবি অস্বীকার: আমি পরীক্ষা করিনি :)
আরনাড পি

15

আমি এটি কীভাবে করেছি (পোস্টারগ্রেসের সাথে জাজানো == ১.৮ পরীক্ষিত, সম্ভবত ১.7)

অবস্থা

app1.YourModel

তবে আপনি এটিতে যেতে চান: অ্যাপ 2 Yআরমোডেল

  1. অ্যাপম 1 থেকে অ্যাপ 2 তে আপনার মডেল (কোড) অনুলিপি করুন।
  2. এটি app2 এ যুক্ত করুন our আপনার মডেল:

    Class Meta:
        db_table = 'app1_yourmodel'
  3. y পাইথন ম্যানেজ.পি মেকমিগ্রেশন অ্যাপ 2

  4. অ্যাপস 2 এ মাইগ্রেশন সহ একটি নতুন স্থানান্তর (উদাহরণস্বরূপ 0009_auto_something.py) তৈরি করা হয়েছে re এবং এখন তৈরি স্থানান্তর = 0009_auto_something.py সরান

  5. আপনি যেমন কাজ করেন ঠিক তেমন অ্যাপ্লিকেশন হিসাবে Y আপনার মডেল সর্বদা রয়েছে, এখন অ্যাপ 1 এর অস্তিত্বটি সরিয়ে দিন our আপনার স্থানান্তর থেকে আপনার মডেল। অর্থ: ক্রিয়েটমোডেল স্টেটমেন্টগুলি এবং তার পরে আপনার ব্যবহৃত প্রতিটি সমন্বয় বা ডেটামাইগ্রেশন মন্তব্য করুন comment

  6. এবং অবশ্যই, অ্যাপ্লিকেশান 1 এর প্রতিটি রেফারেন্স our আপনার প্রকল্পের মাধ্যমে আপনার মডেলটিকে অ্যাপ 2 তে পরিবর্তন করতে হবে our আপনার মডেল। এছাড়াও, এটি ভুলে যাবেন না যে অ্যাপ্লিকেশন 1-এর সমস্ত সম্ভাব্য বিদেশী কীগুলি।

  7. এখন আপনি যদি $ পাইথন ম্যানেজ.পি মাইগ্রেশন করেন তবে কিছুই পরিবর্তন হয়নি, আপনি যখন পাইথন ম্যানেজ.পি মেকমিগ্রেশন করেন তখন নতুন কিছু সনাক্ত করা যায় নি।

  8. এখন সমাপ্তি স্পর্শ: অ্যাপ 2 থেকে ক্লাস মেটা সরিয়ে দিন ourআপনার মডেল এবং পাইথন ম্যানেজ.পি মেকমিগ্রেশন অ্যাপ 2 এবং অজগর ব্যবস্থাপনায় মাইগ্রেট অ্যাপ 2 করুন (আপনি যদি এই মাইগ্রেশনটি দেখেন তবে আপনি এই জাতীয় কিছু দেখতে পাবেন :)

        migrations.AlterModelTable(
        name='yourmodel',
        table=None,
    ),

টেবিল = কিছুই নয়, এর অর্থ এটি ডিফল্ট টেবিল-নাম নেবে, যা এই ক্ষেত্রে অ্যাপ 2_ আপনার মডেল হবে।

  1. সম্পন্ন, ডেটা সংরক্ষণ করা হয়েছে।

মাইগ্রেশনের সময় পিএস এটি দেখতে পাবে যে সেই সামগ্রী_প্রকারের অ্যাপ্লিকেশন 1. আপনার মডেলটি সরানো হয়েছে এবং মোছা যাবে। আপনি এটির জন্য হ্যাঁ বলতে পারেন তবে কেবল আপনি এটি ব্যবহার না করলে। আপনি যদি সেই বিষয়বস্তুর ধরণের এফকে রাখতে অবিচ্ছিন্নভাবে তার উপর নির্ভর করেন তবে হ্যাঁ বা না এখনও উত্তর দেবেন না, তবে সেই সময় নিজেই ডিবিতে যান এবং কন্টেন্টটাইপ অ্যাপ 2.yurmodel মুছে ফেলুন এবং কনটেন্ট টাইপ অ্যাপ্লিকেশনটির পুনরায় নামকরণ করুন। yourmodel to app2.yourmodel, এবং তারপরে কোন উত্তর দিয়ে চালিয়ে যান।


3
যদিও এই সমাধানটি @ ওজানের চেয়ে অবশ্যই "হ্যাকিয়র" এবং এটির জন্য আরও বেশি সম্পাদনা দরকার, এটি আমার পক্ষে দুর্দান্তভাবে কাজ করেছে (এবং মাইগ্রেশন সম্পাদনা করা ঠিক আছে - ডক্স অনুসারে এগুলি সম্পাদনাযোগ্য বলে মনে করা হয়)।
পিজিসিডি

1
সম্ভবত app_label = 'app1'মেটা বিকল্পটিও ব্যবহার করুন ।
ওয়াটওয়ার

জিনিয়াস! ফরেনকি সম্পর্কের জন্য এটি আমার পক্ষে দুর্দান্ত কাজ করেছে। আমি মনে করি এটি ম্যান্টিটোম্যান ক্ষেত্রগুলির জন্যও কাজ করবে।
বাবকেন বর্ধনিয়ান

আমি আপনার পদক্ষেপগুলি অনুসরণ করেছি তবে অ্যাপ 1 এর সাথে সম্পর্কিত কিছু মডেলের ক্ষেত্রটি একটি বিদেশী কী নিয়ে তৈরি হয়েছে যাতে মডেলটির (মাইমোডেল) সাথে পুনরাবৃত্তির সম্পর্ক রয়েছে moved field1 = models.ForeignKey('app1.myModel').আমি যখন মাইগ্রেট করি, তার মতো আমি একটি ভ্যালুইরার পাই যা উল্লেখ করেfield1 was declared with a lazy reference to 'app1.myModel' but app 'app1' doesn't provide model 'MyModel'
দেশা

12

আমি নার্ভাস হ্যান্ড-কোডিং মাইগ্রেশনগুলি পাই ( ওজানের উত্তর অনুসারে প্রয়োজনীয়) তাই হ্যান্ড-কোডিংয়ের পরিমাণটি হ্রাস করার জন্য ওজান এবং মাইকেল এর কৌশলগুলি নীচে একত্রিত করে :

  1. কোনও মডেল স্থানান্তরিত করার আগে, নিশ্চিত হয়ে নিন যে আপনি চালিয়ে একটি পরিষ্কার বেসলাইন নিয়ে কাজ করছেন makemigrations
  2. থেকে মডেল কোড সরান app1করতেapp2
  3. @ মিশেল দ্বারা প্রস্তাবিত হিসাবে, আমরা db_table"নতুন" মডেলের মেটা বিকল্পটি ব্যবহার করে নতুন মডেলটিকে পুরানো ডাটাবেস টেবিলের দিকে নির্দেশ করি :

    class Meta:
        db_table = 'app1_yourmodel'
  4. চালান makemigrations। এটি CreateModelইন app2- DeleteModelইন উত্পন্ন করবে app1। প্রযুক্তিগতভাবে, এই মাইগ্রেশনগুলি হুবহু একই টেবিলটি উল্লেখ করে এবং সরিয়ে ফেলবে (সমস্ত ডেটা সহ) এবং সারণীটি পুনরায় তৈরি করবে।

  5. বাস্তবে, আমরা টেবিলে কিছু করতে (বা প্রয়োজন) চাই না। পরিবর্তনটি হয়েছে তা বিশ্বাস করার জন্য আমাদের কেবল জাজানো দরকার। @ ওজানের উত্তর অনুসারে state_operationsপতাকাটি এটি SeparateDatabaseAndStateকরে। সুতরাং আমরা সব মোড়ানো migrationsএন্ট্রি উভয় মাইগ্রেশন ফাইলের মধ্যে দিয়ে SeparateDatabaseAndState(state_operations=[...])। উদাহরণ স্বরূপ,

    operations = [
        ...
        migrations.DeleteModel(
            name='YourModel',
        ),
        ...
    ]

    হয়ে

    operations = [
        migrations.SeparateDatabaseAndState(state_operations=[
            ...
            migrations.DeleteModel(
                name='YourModel',
            ),
            ...
        ])
    ]
  6. আপনার অবশ্যই এটিও নিশ্চিত করতে হবে যে নতুন "ভার্চুয়াল" CreateModelমাইগ্রেশন যে কোনও মাইগ্রেশন যা মূল টেবিলটি তৈরি করেছে বা পরিবর্তিত হয়েছে তার উপর নির্ভর করে । উদাহরণস্বরূপ, যদি আপনার নতুন স্থানান্তরগুলি app2.migrations.0004_auto_<date>(এর জন্য Create) এবং app1.migrations.0007_auto_<date>(এর জন্য Delete) হয় তবে সবচেয়ে সহজ কাজটি হ'ল:

    • খুলুন app1.migrations.0007_auto_<date>এবং এর app1নির্ভরতা অনুলিপি করুন (যেমন ('app1', '0006...'),)। এটি হ'ল "তাত্ক্ষণিক পূর্ব" স্থানান্তর app1এবং প্রকৃত মডেল বিল্ডিং যুক্তির সমস্তটির উপর নির্ভরতা অন্তর্ভুক্ত করা উচিত।
    • app2.migrations.0004_auto_<date>আপনি কেবলমাত্র তার dependenciesতালিকার অনুলিপিটি অনুলিপিটি খুলুন এবং যুক্ত করুন ।

আপনি ForeignKeyযে মডেলটি চালাচ্ছেন তার সাথে যদি আপনার সম্পর্ক (গুলি) থাকে তবে উপরের কাজটি নাও করতে পারে। এটি ঘটে কারণ:

  • নির্ভরতা স্বয়ংক্রিয়ভাবে ForeignKeyপরিবর্তনের জন্য তৈরি হয় না
  • আমরা ForeignKeyপরিবর্তনগুলি মোড়তে চাই না state_operationsতাই সেগুলি সারণী ক্রিয়াকলাপ থেকে পৃথক কিনা তা আমাদের নিশ্চিত করা উচিত।

দ্রষ্টব্য: জাজানো ২.২ একটি সতর্কতা যুক্ত করেছে ( models.E028) যা এই পদ্ধতিটি ভেঙে দেয়। আপনি এটির সাথে কাজ করতে সক্ষম হতে পারেন managed=Falseতবে আমি এটি পরীক্ষা করিনি।

"সর্বনিম্ন" অপারেশনের সেট পরিস্থিতি অনুসারে পৃথক হয় তবে নিম্নলিখিত পদ্ধতিটি বেশিরভাগ / সমস্ত ForeignKeyস্থানান্তরের জন্য কাজ করা উচিত :

  1. অনুলিপি থেকে মডেল app1থেকে app2, সেট db_table, কিন্তু এমন কোনও এফ কে রেফারেন্স পরিবর্তন।
  2. এতে makemigrationsসমস্ত app2স্থানান্তর চালান এবং মোড়ুন state_operations(উপরে দেখুন)
    • উপরের মত, app2 CreateTableসর্বশেষতম app1স্থানান্তরের জন্য একটি নির্ভরতা যুক্ত করুন
  3. এফকে সমস্ত রেফারেন্সকে নতুন মডেলের দিকে নির্দেশ করুন। আপনি যদি স্ট্রিং রেফারেন্স ব্যবহার না করে থাকেন তবে পুরানো মডেলটিকে নীচে models.pyসরান (এটি সরিয়ে ফেলবেন না) যাতে এটি আমদানীকৃত শ্রেণীর সাথে প্রতিযোগিতা না করে।
  4. চালান makemigrationsতবে কিছুতেই মোড়ানো হবে না state_operations(এফকে পরিবর্তনগুলি আসলে হওয়া উচিত)। সব নির্ভরশীলতার যোগ ForeignKeyমাইগ্রেশন (অর্থাত AlterFieldপর্যন্ত) CreateTableমধ্যে মাইগ্রেশন app2(আপনি পরবর্তী ধাপে এই তালিকা করতে হবে তাদের ট্র্যাক রাখতে)। উদাহরণ স্বরূপ:

    • CreateModelউদাহরণস্বরূপ অন্তর্ভুক্ত মাইগ্রেশনটি সন্ধান করুন app2.migrations.0002_auto_<date>এবং সেই মাইগ্রেশনের নামটি অনুলিপি করুন।
    • সেই মডেলটিতে বিদেশী কী রয়েছে এমন সমস্ত মাইগ্রেশন সন্ধান করুন (যেমন app2.YourModelস্থানান্তরগুলি সন্ধানের জন্য অনুসন্ধান করে:

      class Migration(migrations.Migration):
      
          dependencies = [
              ('otherapp', '0001_initial'),
          ]
      
          operations = [
              migrations.AlterField(
                  model_name='relatedmodel',
                  name='fieldname',
                  field=models.ForeignKey(... to='app2.YourModel'),
              ),
          ]
    • CreateModelনির্ভরতা হিসাবে স্থানান্তর যুক্ত করুন :

      class Migration(migrations.Migration):
      
          dependencies = [
              ('otherapp', '0001_initial'),
              ('app2', '0002_auto_<date>'),
          ]  
  5. থেকে মডেলগুলি সরান app1

  6. চালাও makemigrationsএবং app1মাইগ্রেশনটি মোড়ক করে state_operations
    • সমস্তটির মধ্যে একটি নির্ভরতা যুক্ত করুন ForeignKeyAlterFieldপূর্ববর্তী পদক্ষেপ থেকে স্থানান্তর (যেমন ) ( app1এবং এর মধ্যে মাইগ্রেশন অন্তর্ভুক্ত থাকতে পারে app2)।
    • যখন আমি এই স্থানান্তরগুলি তৈরি করেছি, DeleteTableইতিমধ্যে এর উপর নির্ভরশীলAlterField মাইগ্রেশনগুলির তাই আমার এটির ম্যানুয়ালি প্রয়োগ করার প্রয়োজন হয়নি (যেমন Alterআগে Delete)।

এই মুহুর্তে, জাঙ্গো যেতে ভাল। নতুন মডেলটি পুরানো টেবিলের দিকে ইঙ্গিত করে এবং জ্যাঙ্গোর মাইগ্রেশন এটি নিশ্চিত করেছে যে সবকিছু যথাযথভাবে স্থানান্তরিত হয়েছে। বড় সতর্কতা (@ মাইকেল এর উত্তর থেকে) হ'ল ContentTypeনতুন মডেলের জন্য একটি নতুন তৈরি করা হয়েছে। আপনি যদি ForeignKeyসামগ্রীর ধরণের সাথে (যেমন দ্বারা ) লিঙ্ক করেন তবে ContentTypeটেবিলটি আপডেট করার জন্য আপনাকে একটি স্থানান্তর তৈরি করতে হবে ।

আমি নিজের (মেটা অপশন এবং টেবিলের নাম) পরে পরিষ্কার করতে চেয়েছিলাম তাই আমি নিম্নলিখিত পদ্ধতিটি ব্যবহার করেছি (@ মিশেল থেকে):

  1. অপসারণ db_tableমেটা এন্ট্রি
  2. চালান makemigrationsডাটাবেসটির নতুন নাম উত্পন্ন করতে আবার
  3. এই শেষ স্থানান্তরটি সম্পাদনা করুন এবং তা স্থানান্তরের উপর নির্ভর করে তা নিশ্চিত করুন DeleteTableDeleteখাঁটি যুক্তিযুক্ত হওয়া উচিত বলে মনে করা উচিত নয় , তবে আমি যদি ভুল app1_yourmodelনা করি তবে আমি ত্রুটিগুলিতে চলে এসেছি (যেমন অস্তিত্ব নেই) run

এটি নিখুঁতভাবে কাজ করেছে, আপনাকে ধন্যবাদ! আমি মনে করি না যে শেষ মাইগ্রেশনটি সম্পাদন করা যেমনভাবে যাইহোক নির্ভরতা গাছের নীচে থাকে matters
জেমস Meakin

1
ভাল উত্তর! আমার মনে হয় আপনাকে মাইগ্রেশনগুলিতে একটি ক্লোজিং বন্ধনী যুক্ত করা দরকার ep সেপ্যারেট ডেটাবেসঅ্যান্ডস্টেট, তাই না?
এটিএম

এটি আমার পক্ষে কাজ করেছে। @ জেমসমাকিনের মতো আমিও গত মাইগ্রেশন (৩ য় ধাপ, পুরো উত্তরের শেষ লাইন) সম্পাদনা করিনি এবং এটি এখনও ভাল কাজ করেছে
মেগাওয়াত

দ্বিতীয় দৃশ্যে, এফকে সহ একটি, দ্বিতীয় পদক্ষেপটি আমার পক্ষে একটি ত্রুটিযুক্ত হয়ে যায় যা বোঝায়:table_name: (models.E028) db_table 'table_name' is used by multiple models: app1.Model, app2.Model.
মিহাই জামফির

আমি পদ্ধতিটি কয়েকবার ব্যবহার করেছি। আপনি যদি ডকুমেন্টেশনটি ২.২ ( ডকস.ডজ্যাঙ্গোপ্রজেক্ট / এন / ২.২ / রিফ / চেকস ) এবং ২.১ ( ডকস.ডজ্যাঙ্গোপ্রজেক্ট /en/২.১/ref/checks ) এর সাথে তুলনা করেন , আপনি দেখতে পারবেন এটি ২.২-এ যুক্ত হয়েছে। এটির সাথে কাজ করা সম্ভব হতে পারে managed=Falseতবে আমি যাচাই করার মতো জায়গায় নেই।
ক্লেটন্ডন্ড

1

ডেটা বড় বা খুব জটিল না হলে, তবে বজায় রাখা এখনও গুরুত্বপূর্ণ, অন্য একটি হ্যাকি বিকল্পটি হ'ল:

  • ব্যবহার করে ডেটা ফিক্সচার পান ম্যানেজ.পি ডাম্পডাটা
  • পরিবর্তনের সাথে সম্পর্কিত না হয়ে মডেল পরিবর্তনগুলি এবং সঠিকভাবে মাইগ্রেশনগুলিতে এগিয়ে যান
  • গ্লোবাল পুরানো মডেল এবং অ্যাপের নামগুলি থেকে নতুনটিতে ফিক্সচারগুলি প্রতিস্থাপন করুন
  • ম্যানেজ.পি লোডডাটা ব্যবহার করে ডেটা লোড করুন

1

আমার উত্তরটি https://stackoverflow.com/a/47392970/8971048 এ অনুলিপি করা হয়েছে

যদি আপনাকে মডেলটি সরিয়ে নিতে হয় এবং আপনার আর অ্যাপে অ্যাক্সেস না থাকে (বা আপনি অ্যাক্সেস চান না), আপনি একটি নতুন অপারেশন তৈরি করতে পারেন এবং স্থানান্তরিত মডেলটি না চালিত হলেই একটি নতুন মডেল তৈরি করতে বিবেচনা করতে পারবেন বিদ্যমান।

এই উদাহরণে আমি 'মাইমোডেল' পুরানো_অ্যাপ থেকে মায়াপে যাচ্ছি।

class MigrateOrCreateTable(migrations.CreateModel):
    def __init__(self, source_table, dst_table, *args, **kwargs):
        super(MigrateOrCreateTable, self).__init__(*args, **kwargs)
        self.source_table = source_table
        self.dst_table = dst_table

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        table_exists = self.source_table in schema_editor.connection.introspection.table_names()
        if table_exists:
            with schema_editor.connection.cursor() as cursor:
                cursor.execute("RENAME TABLE {} TO {};".format(self.source_table, self.dst_table))
        else:
            return super(MigrateOrCreateTable, self).database_forwards(app_label, schema_editor, from_state, to_state)


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0002_some_migration'),
    ]

    operations = [
        MigrateOrCreateTable(
            source_table='old_app_mymodel',
            dst_table='myapp_mymodel',
            name='MyModel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=18))
            ],
        ),
    ]

দয়া করে একাধিক প্রশ্নের একই উত্তর যুক্ত করবেন না। সেরাটির উত্তর দিন এবং বাকীটিকে সদৃশ হিসাবে চিহ্নিত করুন। দেখুন বেশ কয়েকটি প্রশ্নের সদৃশ উত্তর যুক্ত করা কি গ্রহণযোগ্য?
পিটার ফ্রিবার্গ

0

এটি মোটামুটি পরীক্ষা করা হয়, তাই আপনার ডিবি ব্যাকআপ করতে ভুলবেন না !!!

উদাহরণ হিসেবে বলা যায়, দুই অ্যাপস আছেন: src_appএবং dst_app, আমরা মডেল স্থানান্তর করতে চান MoveMeথেকে src_appথেকে dst_app

উভয় অ্যাপ্লিকেশনের জন্য খালি স্থানান্তর তৈরি করুন:

python manage.py makemigrations --empty src_app
python manage.py makemigrations --empty dst_app

এর অনুমান করা, যে নতুন মাইগ্রেশন করা যাক XXX1_src_app_newএবং XXX1_dst_app_new, previuos শীর্ষ মাইগ্রেশন হয় XXX0_src_app_oldএবং XXX0_dst_app_old

MoveMeমডেলটির জন্য টেবিলটির নাম পরিবর্তন করে এবং প্রজেক্টস্টেটে এর অ্যাপ_লাবেলের নামকরণ করে এমন একটি ক্রিয়া যুক্ত করুন XXX1_dst_app_newXXX0_src_app_oldমাইগ্রেশনের উপর নির্ভরতা যুক্ত করতে ভুলবেন না । ফলাফল XXX1_dst_app_newস্থানান্তর হ'ল:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

# this operations is almost the same as RenameModel
# https://github.com/django/django/blob/1.7/django/db/migrations/operations/models.py#L104
class MoveModelFromOtherApp(migrations.operations.base.Operation):

    def __init__(self, name, old_app_label):
        self.name = name
        self.old_app_label = old_app_label

    def state_forwards(self, app_label, state):

        # Get all of the related objects we need to repoint
        apps = state.render(skip_cache=True)
        model = apps.get_model(self.old_app_label, self.name)
        related_objects = model._meta.get_all_related_objects()
        related_m2m_objects = model._meta.get_all_related_many_to_many_objects()
        # Rename the model
        state.models[app_label, self.name.lower()] = state.models.pop(
            (self.old_app_label, self.name.lower())
        )
        state.models[app_label, self.name.lower()].app_label = app_label
        for model_state in state.models.values():
            try:
                i = model_state.bases.index("%s.%s" % (self.old_app_label, self.name.lower()))
                model_state.bases = model_state.bases[:i] + ("%s.%s" % (app_label, self.name.lower()),) + model_state.bases[i+1:]
            except ValueError:
                pass
        # Repoint the FKs and M2Ms pointing to us
        for related_object in (related_objects + related_m2m_objects):
            # Use the new related key for self referential related objects.
            if related_object.model == model:
                related_key = (app_label, self.name.lower())
            else:
                related_key = (
                    related_object.model._meta.app_label,
                    related_object.model._meta.object_name.lower(),
                )
            new_fields = []
            for name, field in state.models[related_key].fields:
                if name == related_object.field.name:
                    field = field.clone()
                    field.rel.to = "%s.%s" % (app_label, self.name)
                new_fields.append((name, field))
            state.models[related_key].fields = new_fields

    def database_forwards(self, app_label, schema_editor, from_state, to_state):
        old_apps = from_state.render()
        new_apps = to_state.render()
        old_model = old_apps.get_model(self.old_app_label, self.name)
        new_model = new_apps.get_model(app_label, self.name)
        if self.allowed_to_migrate(schema_editor.connection.alias, new_model):
            # Move the main table
            schema_editor.alter_db_table(
                new_model,
                old_model._meta.db_table,
                new_model._meta.db_table,
            )
            # Alter the fields pointing to us
            related_objects = old_model._meta.get_all_related_objects()
            related_m2m_objects = old_model._meta.get_all_related_many_to_many_objects()
            for related_object in (related_objects + related_m2m_objects):
                if related_object.model == old_model:
                    model = new_model
                    related_key = (app_label, self.name.lower())
                else:
                    model = related_object.model
                    related_key = (
                        related_object.model._meta.app_label,
                        related_object.model._meta.object_name.lower(),
                    )
                to_field = new_apps.get_model(
                    *related_key
                )._meta.get_field_by_name(related_object.field.name)[0]
                schema_editor.alter_field(
                    model,
                    related_object.field,
                    to_field,
                )

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
        self.old_app_label, app_label = app_label, self.old_app_label
        self.database_forwards(app_label, schema_editor, from_state, to_state)
        app_label, self.old_app_label = self.old_app_label, app_label

    def describe(self):
        return "Move %s from %s" % (self.name, self.old_app_label)


class Migration(migrations.Migration):

    dependencies = [
       ('dst_app', 'XXX0_dst_app_old'),
       ('src_app', 'XXX0_src_app_old'),
    ]

    operations = [
        MoveModelFromOtherApp('MoveMe', 'src_app'),
    ]

উপর নির্ভরতা যোগ XXX1_dst_app_newকরার XXX1_src_app_newXXX1_src_app_newনো-অপ মাইগ্রেশন যে নিশ্চিত যে ভবিষ্যতের করতে প্রয়োজন হয় src_appমাইগ্রেশন পর মৃত্যুদন্ড কার্যকর করা হবে XXX1_dst_app_new

সরান MoveMeথেকে src_app/models.pyথেকে dst_app/models.py। তারপরে চালান:

python manage.py migrate

এখানেই শেষ!


নোট করুন যে এই কোডটি কেবলমাত্র জ্যাঙ্গো 1.7 এর জন্য কার্যকর। জাঙ্গো ২.০ এ চেষ্টা করে কাজ হবে না। এর অর্থ হ'ল চলমান মডেলগুলির জন্য এই প্রক্রিয়াটি ব্যবহার করা আপনার জ্যাঙ্গো সংস্করণটি আপগ্রেড করার জন্য রক্ষণাবেক্ষণের ওভারহেড যুক্ত করে।
পৌল '

0

আপনি নিম্নলিখিত (স্বাক্ষরিত) চেষ্টা করতে পারেন:

  1. থেকে মডেল সরাতে src_appকরতেdest_app
  2. স্থানান্তরিত করা dest_app; স্কিমা মাইগ্রেশন সর্বশেষতম src_appস্থানান্তর ( https://docs.djangoproject.com/en/dev/topics/migration/#migration-files ) এর উপর নির্ভর করে তা নিশ্চিত করুন
  3. এতে ডেটা মাইগ্রেশন যুক্ত করুন dest_app, যা থেকে সমস্ত ডেটা অনুলিপি করেsrc_app
  4. স্থানান্তরিত করা src_app; নিশ্চিত করুন যে স্কিমা মাইগ্রেশন সর্বশেষ (ডেটা) স্থানান্তর dest_app- এর উপর নির্ভর করে - যা পদক্ষেপ 3-এর স্থানান্তর

নোট করুন যে আপনি পুরো টেবিলটি সরানোর পরিবর্তে অনুলিপি করবেন , তবে এইভাবে উভয় অ্যাপ্লিকেশনকে অন্য অ্যাপ্লিকেশন সম্পর্কিত কোনও টেবিলের স্পর্শ করতে হবে না, যা আমি মনে করি এটি আরও গুরুত্বপূর্ণ।


0

বলুন আপনি অ্যাপ্লিকেশন_এ থেকে অ্যাপ_বিতে মডেলটি মডেলটিকে সরাচ্ছেন Le

একটি বিকল্প সমাধান হ'ল হাত দ্বারা বিদ্যমান স্থানান্তরগুলি পরিবর্তন করা। ধারণাটি হ'ল প্রতিবার অ্যাপ_এর মাইগ্রেশনগুলিতে থিমোডেল পরিবর্তন করে এমন কোনও অপারেশন দেখলে আপনি সেই অপারেশনটিকে অ্যাপ_বি এর প্রাথমিক স্থানান্তরের শেষে অনুলিপি করেন। এবং প্রতিবার আপনি অ্যাপ_এর মাইগ্রেশনে 'অ্যাপ_এ.ডমোডেল' একটি রেফারেন্স দেখতে পাবেন, আপনি এটিকে 'app_b.TheModel' এ পরিবর্তন করবেন।

আমি কেবল এটি একটি বিদ্যমান প্রকল্পের জন্য করেছি, যেখানে আমি একটি পুনরায় ব্যবহারযোগ্য অ্যাপ্লিকেশনে একটি নির্দিষ্ট মডেলটি বের করতে চেয়েছিলাম। পদ্ধতিটি মসৃণভাবে চলে গেল। আমার ধারণা, যদি অ্যাপ_বি থেকে অ্যাপ_এ-তে রেফারেন্স পাওয়া যায় তবে জিনিসগুলি আরও শক্ত হয়ে উঠবে। এছাড়াও, আমার মডেলটির জন্য আমি একটি ম্যানুয়ালি সংজ্ঞায়িত মেটা.ডিবি_ টেবিল রেখেছিলাম যা সম্ভবত সহায়তা করেছিল।

উল্লেখযোগ্যভাবে আপনি পরিবর্তিত মাইগ্রেশন ইতিহাসের সাথে শেষ করবেন। আসল মাইগ্রেশন প্রয়োগ করে আপনার কাছে একটি ডাটাবেস থাকলেও এটি কোনও ব্যাপার নয়। যদি মূল এবং পুনর্লিখিত উভয় স্থানান্তর একই ডাটাবেস স্কিমার সাথে শেষ হয়, তবে এ জাতীয় পুনর্লিখন ঠিক হওয়া উচিত।


0
  1. পুরানো মডেলের নামগুলি 'মডেল_নাম_ল্ড' এ পরিবর্তন করুন
  2. makemigrations
  3. সম্পর্কিত মডেলগুলিতে অভিন্ন সম্পর্কের সাথে 'মডেল_নেম_নেউ' নামে নতুন মডেল তৈরি করুন (উদাঃ ব্যবহারকারীদের মডেলটিতে এখন ইউজার.ব্লগ_আল্ড এবং ইউজার.ব্লগ_নউ রয়েছে)
  4. makemigrations
  5. একটি কাস্টম মাইগ্রেশন লিখুন যা সমস্ত মডেলকে নতুন মডেলের সারণিতে স্থানান্তর করে
  6. মাইগ্রেশন চালানোর আগে এবং পরে নতুন ডিবি অনুলিপিগুলির সাথে ব্যাকআপ তুলনা করে এই স্থানান্তরগুলি থেকে বেরিয়ে আসার পরীক্ষা করুন
  7. যখন সমস্ত সন্তোষজনক হয়, তখন পুরানো মডেলগুলি মুছুন
  8. makemigrations
  9. নতুন মডেলগুলি সঠিক নাম 'মডেল_নাম_নিউ' -> 'মডেল_নেমে' পরিবর্তন করুন
  10. স্টেজিং সার্ভারে মাইগ্রেশনগুলির পুরো নিখুঁত পরীক্ষা করুন
  11. ব্যবহারকারীদের হস্তক্ষেপ ছাড়াই সমস্ত মাইগ্রেশন চালানোর জন্য কয়েক মিনিটের জন্য আপনার উত্পাদন সাইটটিকে নামিয়ে আনুন

সরানো দরকার এমন প্রতিটি মডেলের জন্য পৃথকভাবে এটি করুন। আমি উত্তরটি পূর্ণসংখ্যায় পরিবর্তন করে এবং বিদেশী কীগুলিতে ফিরে যা বলেছিলাম সেগুলি করার পরামর্শ দেব না mig স্থানান্তর হওয়ার পরে নতুন বিদেশী কী আলাদা হবে এবং সারিগুলির বিভিন্ন আইডি থাকতে পারে এবং আমি কোনও ঝুঁকি চালাতে চাইনি There বিদেশী কীগুলিতে ফিরে যাওয়ার সময় আইডির অমিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.