自定义迁移后如何在模型中添加新字段,在新字段之前访问模型?

How to add new field in model after custom migration which access model before new field?

我有自定义迁移文件,它在 table 用户中创建条目。 初始工作项目有这些迁移:

 1. 001_initial.py # creates model with some fields
 2. 002_custom_user_data.py # adds data in "user" due some middle requirement after some time.

现在我想在此 table 中再添加一列作为“config_data”。 为此,我遵循了以下步骤:

 1. python manage.py makemigrations <app-name> # creates one more migration file` 003_add_config_data_field.py
 2. python manage.py migrate # raise an error

迁移命令引发以下错误。

      Applying my_user.001_initial.py... OK
      Applying my_user.002_custom_user_data.py ...Traceback (most recent call last):
  File "/home/myhome/.local/share/virtualenvs/myproject/lib/python3.9/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
psycopg2.errors.UndefinedColumn: column my_user.config_data does not exist
LINE 1: ..., "my_user"."address",

这是因为在 table 中迁移添加字段 migration(003) 之前,迁移 002 尝试访问 my_user table,这正在提高 UndefinedColumn config_data 错误。

知道如何解决这个问题,因为这些迁移应该适用于新数据库以及更早迁移到 002 的生产 dB。

下面是 002_custom_user_data.py

的迁移
# Generated by Django 3.2.2

from django.db import migrations
from myapp.models import MyUser


def create_user(apps, schema_editor):
    user = MyUser.objects.get_or_create(id=123)
    user.address = 'demo'
    user.save()


def delete_user(apps, schema_editor):
    MyUser.objects.filter(id=123).delete()


class Migration(migrations.Migration):

    dependencies = [
        ('my_user', '001_initial'),
    ]
    operations = [
    migrations.RunPython(create_user, delete_user, elidable=True)
]

谢谢。

您应该导入 历史 模型,而不是您当前的模型。 Django 会在您 运行 迁移之前跟踪模型的外观,您可以使用 apps.get_model(…) method [Django-doc]:

访问此类模型
from django.db import migrations
# No import from myapp.models!


def create_user(apps, schema_editor):
    <strong>MyUser = apps.get_model('my_user', 'MyUser')</strong>
    user = MyUser.objects.get_or_create(id=123)
    user.address = 'demo'
    user.save()


def delete_user(apps, schema_editor):
    <strong>MyUser = apps.get_model('my_user', 'MyUser')</strong>
    MyUser.objects.filter(id=123).delete()


class Migration(migrations.Migration):

    dependencies = [
        ('my_user', '001_initial'),
    ]

我们在这里使用的 MyUser 模型本身不会具有您在 models.py 中定义的模型的所有字段,字段本身也不会具有相同的类型。因此,您可以在这里像当时那样使用模型,从而定义 数据迁移 。例如,如果您创建了一个额外的字段,这些记录将在稍后更新。