Django测试卡在迁移权限创建环节,如何定位与解决?
排查测试卡顿问题的思路与解决方案
我来帮你一步步拆解这个测试卡住的问题,结合你给出的信息,咱们从几个核心方向入手排查:
1. 锁定权限创建后的阻塞点
你的日志停在Adding permission 'Permission object (78)',这说明Django在自动生成权限的流程里卡壳了——虽然你没显式调用django.setup(),但测试运行时Django会自动初始化环境,其中就包含权限生成的逻辑。
- 先检查
vehicles应用的模型:有没有自定义权限?模型Meta类里有没有配置permissions字段?如果有,先注释掉这些自定义权限,重新运行测试,看看是不是自定义权限的逻辑导致了阻塞。 - 可以用
pdb断点或者临时加print语句,在权限创建的关键节点排查:比如在django.contrib.auth.management的权限生成代码里,或者你如果有自定义的post_migratehandler,就在里面加输出,确认到底是哪一步停住了。
2. 代理用户模型的潜在干扰
你用了代理模型作为AUTH_USER_MODEL,虽然代理模型本身不改变数据库结构,但Django的权限系统在关联用户模型时可能有隐藏的兼容问题:
- 检查
authentication.User代理模型的Meta类,有没有设置managed = False?如果是这个配置,可能导致权限系统无法正确关联用户模型的权限关系。 - 可以临时把
AUTH_USER_MODEL改回默认的auth.User,再跑一次测试,排除代理模型带来的影响。
3. Heroku数据库配置的长连接陷阱
你的数据库配置用了dj_database_url.config(conn_max_age=500),长连接在生产环境是好事,但测试环境下反而容易出问题:
- 测试环境建议把
conn_max_age改成0,禁用长连接——因为测试会频繁创建、销毁数据库连接,长连接可能导致连接池耗尽或者死锁。 - 如果本地测试用的是SQLite,
dj_database_url可能会自动转换数据库配置,导致兼容性问题。试试直接在测试配置里硬编码SQLite的设置:DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }
4. 测试环境的初始化问题
虽然你没手动调用django.setup(),但测试运行器(不管是Django自带的manage.py test还是pytest-django)都会自动初始化Django环境,可能在这个过程中出现资源竞争:
- 检查你的测试文件,有没有把模型或Django组件的导入放在模块级别?如果有,可能导致Django提前初始化,引发阻塞。把这些导入移到测试函数内部再试试。
- 用
--keepdb参数运行测试,避免每次测试都重建数据库——有时候数据库迁移的过程中会有隐藏的锁或阻塞,跳过重建可能能验证问题。
快速验证步骤
- 先禁用Heroku的数据库配置,用本地SQLite跑测试,看是否还卡顿;
- 注释掉
vehicles应用的所有自定义权限,重新运行测试; - 临时切换回默认用户模型,确认测试是否正常。
内容的提问来源于stack exchange,提问作者Borko Kovacev
相关产品推荐
相关产品推荐

