如何避免推送到Heroku时应用数据库被重置 实现本地与线上库分离
问题原因
你遇到的问题核心是两处配置错误导致Heroku上的应用没有正确使用平台提供的PostgreSQL数据库,反而一直使用临时文件系统中的SQLite数据库:
- 数据库URI读取逻辑错误:
os.environ.get()的入参是环境变量的键名,你将?sslmode=require参数拼接到了键名中,导致永远读取不到Heroku预置的DATABASE_URL环境变量,只能 fallback 到SQLite路径 - Heroku的dyno实例文件系统是临时的,每次部署、重启都会清空所有本地文件,存储在SQLite里的数据自然会全部丢失,如果你将本地SQLite文件提交到了Git仓库,部署后还会直接用本地的库内容覆盖线上数据
解决步骤
- 修正数据库URI配置代码,正确区分本地和线上环境
替换原来的SQLALCHEMY_DATABASE_URI配置代码为以下内容:
# 读取Heroku环境变量中的数据库地址 pg_uri = environ.get('DATABASE_URL') if pg_uri: # 兼容SQLAlchemy 1.4+对PostgreSQL URI前缀的要求 if pg_uri.startswith('postgres://'): pg_uri = pg_uri.replace('postgres://', 'postgresql://', 1) # 追加ssl连接参数 pg_uri += '?sslmode=require' # 本地无DATABASE_URL环境变量时自动使用SQLite app.config['SQLALCHEMY_DATABASE_URI'] = pg_uri or 'sqlite:///my_database.db'
- 将本地SQLite文件加入
.gitignore,避免误提交到代码仓库
在项目根目录的.gitignore文件中添加一行:
*.db
如果没有这个文件就新建一个,添加后Git会自动忽略所有后缀为db的SQLite文件,不会再将本地数据库推送到Heroku
- 检查启动逻辑,避免自动重置数据库
不要在应用启动时自动执行db.drop_all()、db.create_all()这类会清空重建表的代码,建议使用Flask-Migrate做数据库版本迁移,部署时仅执行flask db upgrade同步表结构,不会影响现有数据
验证效果
配置修改后提交部署到Heroku,线上环境会自动使用Heroku提供的PostgreSQL数据库,数据存储在Heroku的独立数据库服务中,和本地SQLite完全隔离,后续推送代码不会再影响线上数据。
内容的提问来源于stack exchange,提问作者Shiva Kakarla
相关产品推荐
相关产品推荐

