刚接触 Django 那会儿,我总被数据库迁移搞得头大。改个模型字段,跑个命令,结果表结构跟预期不符,数据还丢了,气得想摔键盘。后来摸透了 、 和 这三个命令,才明白所谓的“三步搞定数据表同步更新”其实没那么玄乎。说白了,迁移就是 Django 把 Python 模型翻译成 SQL 语句并执行到数据库里,整个过程自动化程度很高,但前提是你得知道每一步在干嘛。

先说第一步:,这是生成迁移文件的命令。你在 里改了模型,比如新增一个字段,或者删掉一张表,Django 不会自动感知变化,必须先跑 。它会扫描所有应用,对比当前模型和历史迁移记录,生成类似 “0002auto20231001.py” 的文件,里面存着具体的操作指令。比如给 模型加了 字段,迁移文件里就会写 “AddField”。这一步的关键是检查输出,如果提示 “No changes detected”,说明模型没变,或者 Django 没识别到变化,这时要看看 里有没有注册你的应用。我踩过的坑是:改了模型但忘了注册应用,结果 死活不生成文件,排查了半天才发现是配置问题。
第二步:,把迁移文件真正应用到数据库。跑 ,Django 会读取 表,找出还没执行的迁移文件,按顺序执行。比如有迁移文件 “0002auto20231001.py”,里面是给表加字段, 就会发一条 的 SQL 语句。这个过程是事务性的,要么全成功,要么全回滚,所以不用担心半路崩了导致数据不一致。但有个坑:如果数据库里已有数据,新增字段时没有设默认值,Django 会报错。比如给 模型加了 字段,却没设 或 , 会提示 “You are trying to add a non-nullable field without a default”。解决办法很简单:要么在模型里设默认值,要么在迁移时选择 “提供一次性默认值”。我通常选后者,输入一个数字比如 0, 就会帮旧数据填充这个值。
第三步:,是调试神器。跑 ,Django 会把对应迁移文件的 SQL 语句打印出来,不实际执行。比如你改了模型,想看看 Django 会怎么改表结构,用这个命令就能预览。输出像 ,一目了然。这一步对新手特别友好,因为看到 SQL 就能判断迁移逻辑是否正确。我经常在部署前跑一遍 ,确保生成的 SQL 没语法错误,尤其是跨数据库迁移时——开发用 SQLite,生产用 PostgreSQL,语法可能不同,预览一下心里有底。
除了这三步,还有几个实用技巧。比如 ,它会列出所有应用的迁移状态,打勾的是已执行的,空白的是待执行的。你会看到 “0002auto20231001.py [X]”,X 表示已执行,空白表示未执行。这个命令在排查迁移冲突时特别管用。有一次我合并代码时,两个分支都改了同一个模型,生成了不同的迁移文件,结果 报错说 “Migration 0002 has conflicts”。用 一看,发现两个迁移文件都指向同一个父迁移。解决方案是手动删除一个,或者使用 让 Django 自动合并。另一个命令是 ,它会回滚整个应用的所有迁移,表和数据全删掉,慎用,但在开发环境重置时非常方便。
实际工作中,迁移命令的坑往往出在细节上。比如把字段类型从 改成 ,Django 会生成 操作,但如果数据库里有非数字的字符串, 会报错。这时需要先手动清理数据,或者写自定义迁移脚本。再比如删除模型, 会执行 ,如果忘了备份数据,后果不堪设想。所以我养成了习惯:每次跑 前,先用 备份数据。迁移文件冲突在多人协作时也很常见。A、B 两人都改了同一个模型,生成了两个迁移文件, 提示冲突。解决办法是先跑 ,Django 会生成一个合并迁移文件,手动检查无误后再跑 。如果仍有问题,就手动调整迁移文件的依赖顺序。
迁移命令的底层逻辑其实很简单:Django 用一张叫 的表记录执行历史。每次跑 ,它都会读取这张表,找到未执行的迁移文件,然后按依赖顺序执行。因此,如果手动删了迁移文件,或者直接改了数据库结构, 表就会和实际状态不一致,导致 报错。比如删了某个迁移文件,但表里还有记录, 会认为它已经执行过,跳过,后续迁移依赖它时就会出问题。这时可以使用 ,标记迁移已执行但不实际改数据库。这个命令像双刃剑,用得好能快速修复问题,用不好会让状态更乱。建议只在完全理解迁移历史时才使用,否则老老实实回滚重建更安全。
回到开头说的“三步搞定数据表同步更新”,本质就是: 生成计划, 执行计划, 验证计划。这三步环环相扣,少一步都可能出问题。比如直接在数据库里改表结构,不跑迁移,Django 模型和数据库就不一致,下次迁移时会报 “django.db.utils.OperationalError: no such column”。或者改了模型后忘了 ,直接跑 ,它根本不会动数据库。所以别嫌麻烦,每次改模型都跑一遍这三步,养成肌肉记忆。我见过太多人图省事手动改数据库,结果项目上线后数据对不上,加班排查到凌晨。迁移命令虽然啰嗦,却是 Django 最靠谱的数据库管理方式,没有之一。
提醒一句:生产环境跑迁移前,一定先在测试库试一遍。用 预览 SQL,用 检查状态,用 备份数据。这三步花不了十分钟,却能省掉你整夜的修 bug 时间。Django 的迁移系统已经够智能,但数据库这玩意儿再怎么自动化也要留个心眼。毕竟,数据丢了,神仙也救不回来。


