Flask 框架中记录集转 JSON 的方法
Flask 框架里,可以用 jsonify 返回 JSON 数据,但是为什么不用 Python 自带的 json 模块返回 JSON 数据呢?
其实两者是差不多的,jsonify 指明了 是 ,这样做是符合 HTTP 协议的规定的,这就是使用 的原因之一。
Flask 框架中 jsonify 设置 Content-Type 为 application/json 符合 HTTP 协议。将数据库查询结果集转换为字典列表可通过 mappings 方法、自定义函数或 cursor.description 结合 zip 实现。最终通过 jsonify 构造响应对象或 make_response 返回给前端。

Flask 框架里,可以用 jsonify 返回 JSON 数据,但是为什么不用 Python 自带的 json 模块返回 JSON 数据呢?
其实两者是差不多的,jsonify 指明了 是 ,这样做是符合 HTTP 协议的规定的,这就是使用 的原因之一。
Content-Typeapplication/jsonjsonify但是从数据集转 jsonify 有很多细节需要注意,本文将介绍数据集转 jsonify 处理的几种办法。
import config
from exts import db
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask import jsonify, make_response
app = Flask(__name__)
# 从 config.py 文件中获取数据库配置信息
app.config.from_object(config)
db = SQLAlchemy(app)
@app.route('/weather', methods=['GET', 'POST'])
def getjson():
pass
if __name__ == '__main__':
app.run()
下面代码封装了一个将记录集和数据字段名称转换为字典列表的函数,通过 cursor.description 获取数据字段元数据,通过 zip 将字段名和结果封装起来。
def rows_as_dicts(cursor):
# 将游标集转换为字典类型列表
col_names = [i[0] for i in cursor.description]
return [dict(zip(col_names, row)) for row in cursor]
下面代码是通过 mappings 方法将结果集转换为字典列表。
sql = "select userid,username,password,personalname,birthday,sex,phone,postcard,address from userinfo"
result = db.session.execute(sql)
# 1、mappings 方式,最简单直接
results_as_dict = result.mappings().all()
# [{'userid': 1, 'username': 'admin', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-08', 'sex': '男', 'phone': 'eeee', 'postcard': 'dddd', 'address': '44444444'},
# {'userid': 2, 'username': 'admin1', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-03', 'sex': '男', 'phone': '', 'postcard': '', 'address': '423'},
# ...
# {'userid': 17, 'username': 'admin33333', 'password': '1qaz!QAZ', 'personalname': '333', 'birthday': '2022-02-17', 'sex': '男', 'phone': '3333', 'postcard': '333', 'address': '333333'}]
result = db.session.execute(sql)
print('result=', result)
# result= <sqlalchemy.engine.cursor.CursorResult object at 0x0000025FF5B36438>
print('type(result)=', type(result))
# type(result)= <class 'sqlalchemy.engine.cursor.CursorResult'>
result = db.session.execute(sql).fetchall()
print('result=', result)
# result= [(1, 'admin', '1qaz!QAZ', 'adminstrator', '1976-11-08', '男', 'eeee', 'dddd', '44444444'),
# (2, 'admin1', '1qaz!QAZ', 'adminstrator', '1976-11-03', '男', '', '', '423'),
print('type(result)=', type(result))
# type(result)= <class 'list'>
result = db.session.execute(sql).cursor
print('result=', result)
# result= <sqlite3.Cursor object at 0x0000025FF5AC6B20>
print('type(result)=', type(result))
# type(result)= <class 'sqlite3.Cursor'>
# 2、自定义函数,将游标集转换为字典列表
cursor = db.session.execute(sql).cursor
result = rows_as_dicts(cursor)
# [{'userid': 1, 'username': 'admin', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-08', 'sex': '男', 'phone': 'eeee', 'postcard': 'dddd', 'address': '44444444'},
# {'userid': 2, 'username': 'admin1', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-03', 'sex': '男', 'phone': '', 'postcard': '', 'address': '423'},
# ...
# {'userid': 17, 'username': 'admin33333', 'password': '1qaz!QAZ', 'personalname': '333', 'birthday': '2022-02-17', 'sex': '男', 'phone': '3333', 'postcard': '333', 'address': '333333'}]
# 关于 cursor 和 cursor.description 介绍
cursor = db.session.execute(sql).cursor
# cursor.description 返回元祖类型元数据
# print('cursor.description=',cursor.description)
# (('userid', None, None, None, None, None, None),
# ('username', None, None, None, None, None, None),
# ('password', None, None, None, None, None, None),
# ...
# ('address', None, None, None, None, None, None))
# [i[0] for i in cursor.description],通过迭代获取元数据信息
# print('[i[0] for i in cursor.description]=',[i[0] for i in cursor.description])
# ['userid', 'username', 'password', 'personalname', 'birthday', 'sex', 'phone', 'postcard', 'address']
# print('[row for row in cursor]=',[row for row in cursor])
# [(1, 'admin', '1qaz!QAZ', 'adminstrator', '1976-11-08', '男', 'eeee', 'dddd', '44444444'),
# (2, 'admin1', '1qaz!QAZ', 'adminstrator', '1976-11-03', '男', '', '', '423'),
# ...
# (17, 'admin33333', '1qaz!QAZ', '333', '2022-02-17', '男', '3333', '333', '333333')]
# db.session.execute 返回 CursorResult
r = db.session.execute(sql)
# db.session.execute(sql)= <sqlalchemy.engine.cursor.CursorResult object at 0x0000020353A069B0>
# 通过 fetchall() 获取记录集
result = r.fetchall()
# [(1, 'admin', '1qaz!QAZ', 'adminstrator', '1976-11-08', '男', 'eeee', 'dddd', '44444444'),
# (2, 'admin1', '1qaz!QAZ', 'adminstrator', '1976-11-03', '男', '', '', '423')
# ...
# (17, 'admin33333', '1qaz!QAZ', '333', '2022-02-17', '男', '3333', '333', '333333')]
# 3、通过
resultproxy = db.session.execute(sql)
resultdict = []
# resultproxy= <sqlalchemy.engine.cursor.CursorResult object at 0x000001D48DB93B00>
# resultproxy.keys= <bound method _WithKeys.keys of <sqlalchemy.engine.cursor.CursorResult object at 0x000001D48DB93B00>>
colname = [i[0] for i in cursor.description]
print('colname=', colname)
for rowproxy in resultproxy:
rowresult = dict(zip(colname, rowproxy))
# rowproxy= (1, 'admin', '1qaz!QAZ', 'adminstrator', '1976-11-08', '男', 'eeee', 'dddd', '44444444')
# rowproxy type= <class 'sqlalchemy.engine.row.Row'>
# rowresult= {'userid': 1, 'username': 'admin', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-08', 'sex': '男', 'phone': 'eeee', 'postcard': 'dddd', 'address': '44444444'}
resultdict.append(rowresult)
# rowresult =
# [{'userid': 1, 'username': 'admin', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-08', 'sex': '男', 'phone': 'eeee', 'postcard': 'dddd', 'address': '44444444'},
# {'userid': 2, 'username': 'admin1', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'birthday': '1976-11-03', 'sex': '男', 'phone': '', 'postcard': '', 'address': '423'},
# ...
# {'userid': 17, 'username': 'admin33333', 'password': '1qaz!QAZ', 'personalname': '333', 'birthday': '2022-02-17', 'sex': '男', 'phone': '3333', 'postcard': '333', 'address': '333333'}]
下面是讲字典列表 json 化,并通过 response 响应回前端的两种方式。
# jsonify 及返回响应的两种方法
# 1、通过构造 response 方式
response = jsonify(resultdict)
response.status_code = 200 # or 400 or whatever
# ---------------response.data----------------
print('response.data',response.data)
# response.data b'[{"address":"44444444","birthday":"1976-11-08","password":"1qaz!QAZ","personalname":"adminstrator","phone":"eeee","postcard":"dddd","sex":"\\u7537","userid":1,"username":"admin"},
# {"address":"423","birthday":"1976-11-03","password":"1qaz!QAZ","personalname":"adminstrator","phone":"","postcard":"","sex":"\\u7537","userid":2,"username":"admin1"},
# ...
# {"address":"333333","birthday":"2022-02-17","password":"1qaz!QAZ","personalname":"333","phone":"3333","postcard":"333","sex":"\\u7537","userid":17,"username":"admin33333"}]\n'
# ---------------response.json----------------
# response.json [{'address': '44444444', 'birthday': '1976-11-08', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'phone': 'eeee', 'postcard': 'dddd', 'sex': '男', 'userid': 1, 'username': 'admin'},
# {'address': '423', 'birthday': '1976-11-03', 'password': '1qaz!QAZ', 'personalname': 'adminstrator', 'phone': '', 'postcard': '', 'sex': '男', 'userid': 2, 'username': 'admin1'},
# ...
# {'address': '333333', 'birthday': '2022-02-17', 'password': '1qaz!QAZ', 'personalname': '333', 'phone': '3333', 'postcard': '333', 'sex': '男', 'userid': 17, 'username': 'admin33333'}]
# response.headers Content-Type: application/json
# Content-Length: 3012
# ---------------response.headers----------------
# response.headers Content-Type: application/json
# ---------------response.status_code----------------
# response.status_code 200
# ---------------response.content_length----------------
# Content-Length: 3012
return response
# 2、通过 make_response 方式
# return make_response(jsonify(resultdict), 200)

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online