修改schema后Flask+uWSGI提示列不存在,但列实际存在求助
解决思路:uWSGI启动Flask应用时SQLite列不存在的问题
以下是针对该问题的排查和解决方向:
检查uWSGI的工作目录
直接运行Flask和通过uWSGI启动时,程序的工作目录可能不一致。如果你的数据库路径用的是相对路径(比如instance/app.db),uWSGI可能加载了另一个位置的旧数据库文件。- 解决:在uWSGI配置文件中通过
chdir指定应用根目录,或者在Flask工厂函数中用绝对路径定义数据库位置:import os from flask import Flask def create_app(): app = Flask(__name__) # 用绝对路径指定数据库文件 app.config['DATABASE'] = os.path.join(os.path.abspath(app.instance_path), 'app.db') # 确保instance目录存在 try: os.makedirs(app.instance_path) except OSError: pass # 其他初始化逻辑 - 验证:在uWSGI启动脚本中打印当前工作目录,或者直接用绝对路径替换数据库路径测试。
- 解决:在uWSGI配置文件中通过
彻底清理uWSGI残留进程
uWSGI的worker进程可能残留了旧的数据库连接或代码缓存,即使你更新了数据库和代码,这些进程仍在使用旧数据。- 解决:完全停止所有uWSGI进程后再重启。比如用
uwsgi --stop uwsgi.pid(如果配置了pid文件),或者执行pkill uwsgi确保所有相关进程终止,然后重新启动服务。 - 注意:如果启用了
lazy-apps选项,需要重启master进程才能加载新代码,仅重启worker无效。
- 解决:完全停止所有uWSGI进程后再重启。比如用
确认虚拟环境一致性
手动运行应用时激活的虚拟环境,可能和uWSGI配置中指定的虚拟环境不一致,导致加载了旧版本的应用代码(比如未更新的模型定义)。- 解决:在uWSGI配置文件中明确指定虚拟环境路径:
virtualenv = /path/to/your/project/venv - 验证:在应用中添加一个临时接口,打印当前代码的文件路径,确认uWSGI加载的是最新部署的代码。
- 解决:在uWSGI配置文件中明确指定虚拟环境路径:
核对数据库初始化的目标文件
执行flask init-db时,可能因为环境变量(比如FLASK_APP)不正确,初始化的是另一个路径的数据库文件,而uWSGI加载的是未更新的旧文件。- 解决:执行初始化命令时明确指定环境变量,确保和uWSGI启动时一致:
FLASK_APP=your_app_module FLASK_ENV=production flask init-db - 验证:对比手动运行和uWSGI启动时所使用的数据库文件的MD5值,确认是同一个文件。
- 解决:执行初始化命令时明确指定环境变量,确保和uWSGI启动时一致:
检查SQLite文件权限
uWSGI通常以非 root 用户(比如www-data)运行,如果该用户没有读取最新数据库文件的权限,或者初始化时因权限不足创建了新的空数据库,就会出现列不存在的错误。- 解决:修改数据库文件和instance目录的所有者及权限:
chown www-data:www-data /path/to/app/instance/app.db chmod 644 /path/to/app/instance/app.db
- 解决:修改数据库文件和instance目录的所有者及权限:
确认模型定义与数据库同步
如果使用了ORM(比如SQLAlchemy),即使数据库schema更新了,若uWSGI加载的代码中模型类未同步修改,依然会触发字段不存在的错误。- 解决:检查CI/CD是否正确部署了最新代码,重启uWSGI时确保加载的是更新后的模型文件。
内容的提问来源于stack exchange,提问作者hantaray
相关产品推荐
相关产品推荐

