数据迁移最容易踩的坑:为什么不能用模型上的方法?为什么不能 import 真实模型?怎么回填才不会慢?这篇用 10 万行 PostgreSQL 数据把这几个问题一次跑清楚。
Operations to perform: Apply all migrations: contenttypes, lab Running migrations: Applying lab.0002_fill_full... 历史模型 Person 是否有自定义方法 full_name: False 类: __fake__.Person Python 循环 + bulk_update(20000 行): 1.55 s 一条 UPDATE … SET display = first_name || " " || last_name(100000 行): 0.18 s OK
迁移执行时,Django 用「迁移状态」构造一份临时的模型类(__fake__ 模块)。它的字段与该迁移那一刻一致,但没有任何方法、管理器(除非迁移里声明 use_in_migrations)、信号连接。
上面演示里「Python 循环」是读出来、改字段、bulk_update;「一条 UPDATE」是 update(display=Concat(F(...), Value(' '), F(...)))。耗时数字来自迁移自己打印的计时(本机 PostgreSQL,包含事务)。
已填充的行数: 100000 migrate lab 0001(回退)→ ['Unapplying lab.0002_fill_full... OK'] 回退后 display 非空的行数: 0
回退时执行你提供的反向函数;不提供会 IrreversibleError(第 54 篇)。
在全新库上从头 migrate(真实模型已多了 later 字段,但 0002 时这一列还不存在):
django.db.utils.ProgrammingError: column lab_person.later does not exist这个 bug 在开发库上看不出来(表已经是最新的),只在新环境从头迁移时才炸。