如何通过SQLAlchemy关联查询在Flask应用中返回flat resultset?
实现SQLAlchemy关联查询返回扁平化结果集
有几种方法可以让你得到单一结构的扁平化结果,而非包含ORM对象的元组:
方法1:直接指定查询字段(推荐)
在query()中明确列出需要返回的具体字段,SQLAlchemy会直接返回由这些字段值组成的元组,完全匹配你想要的结构:
from app import app, db from app.models import User, Department @app.route("/index") def index(): # 用label()可以给字段起别名,方便后续识别 results = db.session.query( User.id.label('user_id'), User.first_name, User.last_name, Department.name.label('department_name') ).join(Department, Department.id == User.department_id, isouter=True).all() # 返回的results结构:[(1, '张三', '李四', '技术部'), (2, '王五', '赵六', None), ...] return render_template('index.html', results=results)
方法2:使用with_entities筛选字段
如果已经写了基于ORM对象的查询,可以用with_entities()来指定需要提取的字段,效果和方法1一致:
@app.route("/index") def index(): results = db.session.query(User, Department)\ .join(Department, Department.id == User.department_id, isouter=True)\ .with_entities( User.id, User.first_name, User.last_name, Department.name ).all() return render_template('index.html', results=results)
方法3:事后处理ORM结果
如果必须保留原有的ORM对象查询(比如需要用对象做其他操作),可以遍历查询结果,手动提取属性生成扁平化结构:
@app.route("/index") def index(): query_results = db.session.query(User, Department)\ .join(Department, Department.id == User.department_id, isouter=True).all() flat_results = [] for user, dept in query_results: # 处理左外连接可能出现的空Department对象 dept_name = dept.name if dept else None flat_results.append((user.id, user.first_name, user.last_name, dept_name)) return render_template('index.html', results=flat_results)
多表关联扩展
如果后续需要关联更多表(比如Company),只需要在查询字段中添加对应表的属性即可,比如:
results = db.session.query( User.id, User.first_name, Department.name, Company.name.label('company_name') ).join(Department, Department.id == User.department_id, isouter=True)\ .join(Company, Company.id == Department.company_id, isouter=True).all()
内容的提问来源于stack exchange,提问作者Rob Wissink
相关产品推荐
相关产品推荐

