Flask SQLAlchemy操作SQLite报no such table: object错误
报错原因
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: object 触发原因是你仅定义了Object数据库模型,但从未执行表创建操作,SQLite库中不存在对应表,所有涉及数据库读写的接口都会触发该错误。不操作数据库的index()接口不依赖数据表,因此可以正常访问。
另外你的代码还存在两个隐性问题:
- 模型中
oid、size字段定义为整数类型,但POST提交的JSON参数、GET接口路径传入的oid均为字符串格式,直接使用可能触发类型不匹配错误 - Flask-SQLAlchemy 3.0及以上版本执行数据库操作需要主动推入应用上下文,直接调用数据库相关方法会抛上下文错误
修复方案
- 先删除项目目录下已生成的旧
db.sqlite3文件(如果存在),避免历史文件干扰 - 在模型定义完成后,通过应用上下文调用
db.create_all()生成所有定义的数据表 - 对传入的参数做整数类型转换,匹配数据库字段类型
修改后的可运行代码如下:
from flask import Flask, request from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite3' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) class Object(db.Model): oid = db.Column(db.Integer, primary_key=True) size = db.Column(db.Integer) def __repr__(self): return f'Object: {self.oid}, Size: {self.size}' # 推入应用上下文,创建所有定义的数据表 with app.app_context(): db.create_all() @app.route('/') def index(): return 'DSAP_2022' @app.route('/data/<oid>', methods=['GET']) def getObject(oid): obj = Object.query.filter_by(oid=int(oid)).first() if obj is None: return 'Object not found', 404 return repr(obj) @app.route('/data', methods=['POST']) def putObject(): obj = Object( oid=int(request.json['oid']), size=int(request.json['size']) ) db.session.add(obj) db.session.commit() return 'OK' if __name__ == '__main__': app.run()
补充说明:
db.create_all()只会创建数据库中不存在的表,不会同步模型的字段修改。如果后续调整了模型字段定义,需要删除旧的db.sqlite3文件重新启动生成新表,复杂场景可以引入Flask-Migrate实现数据库版本迁移。
内容的提问来源于stack exchange,提问作者Joey Joestar
相关产品推荐
相关产品推荐

