Heroku Postgres异常:执行db.create_all()后数据库未创建
db.create_all() 我一眼就揪出问题所在了——你的生产环境配置里用的是SQLite数据库,而不是你创建的Heroku Postgres实例!
问题根源
看你app.py里的配置逻辑:当ENV='prod'时,你指定的数据库URI是sqlite:///contaook.db。这意味着你在Heroku上运行的代码其实是在操作本地文件型的SQLite数据库,完全没用到Heroku Postgres。所以你执行db.create_all()没报错,但表都建在SQLite的临时文件里了(Heroku的dyno重启后这些文件会直接消失),自然在Heroku Postgres里看不到任何表。
修复步骤
1. 修正生产环境的数据库URI配置
Heroku会自动为你的Postgres实例设置DATABASE_URL环境变量,你直接读取这个变量就行,不用手动写用户名和密码。另外注意SQLAlchemy 1.4+版本只认postgresql://开头的URI,而Heroku的默认URI是postgres://,需要做个替换:
else: app.debug=False import os # 获取Heroku提供的Postgres连接地址 uri = os.environ.get('DATABASE_URL') # 适配SQLAlchemy 1.4+的URI格式要求 if uri.startswith('postgres://'): uri = uri.replace('postgres://', 'postgresql://', 1) app.config['SQLALCHEMY_DATABASE_URI'] = uri
2. 重新部署应用到Heroku
把修改后的代码推送到Heroku,让新配置生效:
git add app.py git commit -m "Switch production DB to Heroku Postgres" git push heroku main
3. 再次执行数据库表创建
重新进入Heroku的Python交互环境执行创建命令:
heroku run python
在交互窗口里输入:
>>> from app import db >>> db.create_all() >>> exit()
验证方法
现在你可以通过Heroku CLI登录Postgres控制台查看表:
heroku pg:psql
输入\dt命令就能看到你创建的所有表了。
额外提醒
永远不要在Heroku上用SQLite——Heroku的dyno是临时文件系统,所有本地文件会在dyno重启后丢失,Postgres才是生产环境的正确选择。另外可以用heroku addons命令确认Postgres插件已经正确添加到你的应用中。
内容的提问来源于stack exchange,提问作者user12970247

