Django中migrate和makemigrations修改哪些文件?残留痕迹排查
makemigrations与migrate命令的修改范围 两个命令的操作边界非常清晰,不会随意改动项目文件:
makemigrations:仅会向所有已注册App的migrations/目录下写入新的迁移脚本文件,不操作数据库,也不修改项目其他位置的代码、配置。只要你手动清空了所有自定义App下migrations/目录里除__init__.py之外的文件,该命令生成的所有历史迁移记录就已经被完全清除。注意Django内置App(如auth、admin)的迁移脚本存放在Python环境的Django安装目录下,不属于项目源码范畴,不需要手动删除。migrate:完全不修改项目源码目录下的任何文件,核心逻辑是读取迁移脚本,对配置指向的目标数据库执行表结构创建/变更、数据写入操作,同时会在数据库内置的django_migrations表中记录所有已执行的迁移版本号。
旧用户数据残留的可能位置
你遇到的django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username报错,本质是向auth_user表写入已存在的用户名时触发了唯一约束,说明当前连接的数据库中已经存在对应用户名记录,残留痕迹只会出现在以下位置,和你是否清空migrations文件夹没有直接关系:
- 残留的SQLite数据库文件:如果使用Django默认的SQLite数据库,检查
settings.py中DATABASES配置指定的路径下(默认是项目根目录的db.sqlite3)是否存在旧的数据库文件。该文件不会随migrations文件夹清空自动删除,只要文件存在,之前执行migrate创建的表结构、写入的用户数据就会完整保留。很多人部署时没有把db.sqlite3加入.gitignore,会直接把本地测试生成的数据库文件随源码一起打包上传到部署环境。 - 配置指向的旧外部数据库:如果配置的是MySQL/PostgreSQL等外部数据库,检查当前连接地址、端口、库名、账号对应的实例是否是之前测试用过的旧库。哪怕你换了全新的部署目录,只要数据库连接配置没变,就会直接读取到之前写入的旧用户数据。
- 未做存在性判断的自动用户创建逻辑:如果数据库确实是全新的,检查是否在AppConfig的
ready()方法、迁移后信号、启动脚本中写了自动创建默认用户/超级用户的逻辑,且没有加用户存在性判断——Django开发服务默认会触发两次ready()方法执行,第一次创建用户成功后,第二次执行重复插入就会触发该报错。
排查解决步骤
- 先打开
settings.py核对DATABASES配置,确认当前项目实际连接的数据库地址与类型 - 如果是SQLite数据库,找到配置路径下的db文件直接删除,重新执行
makemigrations、migrate即可得到完全干净的库 - 如果是外部数据库,用客户端连接到对应库,查询
auth_user表确认是否存在旧数据,确认无用后清空库内所有表,再重新执行迁移 - 全局搜索创建用户的逻辑,所有自动创建用户的代码必须先通过
User.objects.filter(username=xxx).exists()判断存在性,再执行创建操作
内容的提问来源于stack exchange,提问作者user19413311
相关产品推荐
相关产品推荐

