Django数据迁移如何执行?

访客 全栈框架 2

本文目录导读:

  1. 结构迁移(最常用)
  2. 数据迁移(处理已有数据)
  3. 常用命令速查
  4. 常见注意事项
  5. 完整示例:添加字段 + 填充数据

在Django中执行数据迁移主要分两种情况:创建/修改模型后的结构迁移(如添加字段、改字段类型)和数据迁移(如批量修改现有数据内容),以下是详细执行步骤:


结构迁移(最常用)

这是修改数据库表结构的标准流程(比如新增一个 age 字段)。

修改 models.py

# models.py
class User(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField(null=True, blank=True)  # 新加的字段

生成迁移文件

python manage.py makemigrations
  • Django 会检测模型与数据库的差异,自动生成迁移文件(在 app/migrations/ 目录下,0002_user_age.py)。
  • 注意:如果新增字段没有设默认值且不允许为空,会提示你输入默认值或设为 null=True

执行迁移

python manage.py migrate
  • 这会真正修改数据库表(添加 age 列)。
  • 会按顺序执行所有未应用的迁移文件(包括依赖的其他app迁移)。

数据迁移(处理已有数据)

当需要修改或填充现有数据时(给所有用户设置默认年龄为18),不能用结构迁移,而要用数据迁移

创建一个空数据迁移文件

python manage.py makemigrations --empty yourappname
  • 生成一个只包含 dependencies 的空迁移文件。

编辑迁移文件,添加数据操作

# yourappname/migrations/0003_auto_xxx.py
from django.db import migrations
def set_default_age(apps, schema_editor):
    User = apps.get_model('yourappname', 'User')
    for user in User.objects.all():
        user.age = 18
        user.save(update_fields=['age'])
class Migration(migrations.Migration):
    dependencies = [
        ('yourappname', '0002_...'),  # 前一个迁移
    ]
    operations = [
        migrations.RunPython(set_default_age),
    ]

执行数据迁移

python manage.py migrate
  • Django 会执行 RunPython 中的函数,逐条更新数据。

常用命令速查

命令 作用
python manage.py showmigrations 查看哪些迁移已应用(打[X]),哪些未应用
python manage.py migrate app_name 0001 回退到某个迁移版本(0001 是迁移文件名前缀)
python manage.py migrate app_name zero 撤销该app所有迁移(表会被删除!小心使用)
python manage.py sqlmigrate app_name 0002 预览某个迁移对应的SQL语句(不执行)

常见注意事项

新增必填字段且无默认值

如果新增字段 age = models.IntegerField() (不允许为空),执行 makemigrations 时Django会问:

You are trying to add a non-nullable field 'age' to user without a default...

此时你必须:

  • 输入一个默认值(仅用于迁移时填充旧数据)
  • 或者改为 null=True 然后做数据迁移补数据

迁移冲突

多人协作时,如果别人也生了相同序号迁移文件(如两个人都做了 0002_xxx.py),执行 migrate 会报错,解决方案:

  • python manage.py migrate app_name 0001 回滚到冲突前版本
  • 删除你本地多余的迁移文件(保留别人的)
  • 重新 makemigrations 生成新的

生产环境迁移策略

  • 先备份数据库
  • 尽量在低峰期执行(会锁定表)
  • 大表大规模数据迁移建议拆成多个小批次(使用 RunPython 中带 batch_size 或分页逻辑)

完整示例:添加字段 + 填充数据

# 1. models.py 加字段
class User(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField(null=True)   # 先为空,后续填充
# 2. 生成结构迁移
# python manage.py makemigrations
# python manage.py migrate
# 3. 生成数据迁移
# python manage.py makemigrations --empty yourappname
# 4. 编辑数据迁移文件,加入:
def fill_age(apps, schema_editor):
    User = apps.get_model('yourappname', 'User')
    for i, user in enumerate(User.objects.iterator()):
        user.age = 20 + i % 10   # 示例填充逻辑
        user.save()
# 5. 执行数据迁移
# python manage.py migrate

总结一句话:结构改模型 → makemigrations → 数据想改就用 RunPython 写数据迁移 → 最后统一 migrate

标签: makemigrations migrate

抱歉,评论功能暂时关闭!