部署于Heroku的Django项目出现用户创建对象无故随机删除问题
问题根因排查方向
1. 优先排查数据库配置 fallback 风险
你当前的数据库配置存在严重的 fallback 逻辑漏洞:dj_database_url.config() 在读取不到对应环境变量时会返回空字典,此时 DATABASES['default'].update() 不会覆盖任何默认配置,程序会直接使用本地 SQLite 数据库。
而 Heroku 的临时文件系统会在 dyno 重启、部署、冷启动切换实例时清空所有本地文件,写入 SQLite 的数据会直接丢失。你误以为自己全程使用 Postgres,但实际很可能存在部分请求落到 SQLite 上的情况:
- 执行
heroku config:get DATABASE_URL确认环境变量是否存在且指向正确的 Postgres 实例 - 建议修改配置逻辑,生产环境下如果读取不到 Postgres 配置直接抛出异常,禁止 fallback 到 SQLite:
import dj_database_url import os db_from_env = dj_database_url.config(conn_max_age=500) if not db_from_env and os.getenv('ENV') == 'production': raise RuntimeError('Postgres config not found') DATABASES['default'].update(db_from_env)
2. 排查Django模型级联删除逻辑
Django 外键默认的 on_delete=models.CASCADE 是非常常见的误删原因:如果某个父对象被删除,所有关联的子对象会被自动级联删除,很多开发者会忽略这个配置的影响。
- 检查所有涉及用户生成对象的模型外键配置
- 建议在生产环境开启 DELETE 操作日志,记录所有删除请求的执行主体、时间和对应SQL,方便后续回溯:
# settings.py 日志配置示例 LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'level': 'DEBUG', 'propagate': False, }, }, }
3. 排查Heroku Postgres运行状态
- 执行
heroku logs --postgres查看数据库运行日志,确认是否有非预期的 DELETE 语句执行,或者实例故障、备份恢复等操作记录 - 确认已开启Heroku Postgres自动备份,拿丢失数据时间段前后的备份对比:如果数据在旧备份中存在、新备份中不存在,说明是被主动删除;如果旧备份中也不存在,说明数据从一开始就没写入Postgres,直接落到了本地SQLite中。
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

