自定义迁移后如何在模型中添加新字段,在新字段之前访问模型?
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
中定义的模型的所有字段,字段本身也不会具有相同的类型。因此,您可以在这里像当时那样使用模型,从而定义 数据迁移 。例如,如果您创建了一个额外的字段,这些记录将在稍后更新。
我有自定义迁移文件,它在 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
中定义的模型的所有字段,字段本身也不会具有相同的类型。因此,您可以在这里像当时那样使用模型,从而定义 数据迁移 。例如,如果您创建了一个额外的字段,这些记录将在稍后更新。