部署在Heroku的Discord机器人关联GitHub仓库后SQLite数据库无法更新问题
核心问题根因
Heroku平台的dyno运行实例采用临时易失性文件系统:每次你部署新代码、dyno实例24小时自动滚动重启、或者实例资源调整重启时,所有运行期间写入本地的文件都会被重置为GitHub仓库内的原始版本。你本地测试时使用的是本地持久化存储的SQLite文件,所以功能正常,线上写入的list.sql文件并不会被持久保存,自然无法看到更新。
解决方案
- 优先更换为外置持久化数据库
SQLite是本地文件型数据库,天生不适合Heroku这类无状态运行环境。你可以更换为Heroku官方提供的PostgreSQL服务(存在免费额度套餐),或者其他可公网访问的MySQL、PostgreSQL服务,所有数据写入外置独立数据库即可解决数据丢失问题。 - 不建议坚持使用SQLite的替代方案
如果必须使用SQLite,你需要将数据库文件存储到独立的附加存储服务中,每次实例启动时拉取最新的数据库文件,写入后实时同步回存储服务,但该方案实现复杂度高、稳定性差,远不如直接更换外置数据库。
代码优化建议
- 修复SQL注入风险:不要使用f-string直接拼接SQL语句,改用参数化查询写法:
# 原错误写法 c.execute(f"SELECT * FROM list WHERE ID = {player.id}") # 修正后的参数化写法 c.execute("SELECT * FROM list WHERE ID = ?", (player.id,)) # 插入语句同理也要改 c.execute("INSERT INTO list VALUES(?)", (player.id,))
- 修复缩进错误:你贴出的代码中
if c.fetchone() is not None:这一行的缩进层级错误,需要和上一行的gg = c.execute(...)保持相同缩进,否则会触发语法错误。 - 补充连接关闭逻辑:每次数据库操作完成后主动关闭连接,避免连接泄漏:
conn.commit() conn.close()
内容的提问来源于stack exchange,提问作者gamer_ lmfao
相关产品推荐
相关产品推荐

