添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Flask 实现 Rest API (02) - 查询结果转换为 json 字符串 这篇文章中,介绍了基于原生 CRUD 将查询结果转为 json 格式的方法。本篇接着介绍使用 Flask-SqlAlchemy 时,如何将查询结果转换为 json 格式。过程是先将查询的结果转为 dict/list,然后将 dict/list 转为 json,dict/list 转 json 是 Python 内置的功能,所以关键在如何将 Python 对象转换为 dict/list。

如果不使用第三方模块,需要手工编写代码来处理映射关系。假设在 MySQL 数据库中有一个 user 表,结构如下:


如下代码实现了将所有用户信息通过 response 返回到客户端:

from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
import os
from collections import OrderedDict
app = Flask(__name__)
# app.configurations
app.config['SECURITY_KEY'] = 'you will never guess'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DB_URI']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['JSON_SORT_KEYS'] = False
db = SQLAlchemy(app)
class User(db.Model):
    __tablename__ = 'user'
    USER_ID = db.Column(db.Integer, primary_key=True)
    USERNAME = db.Column(db.String(20))
    CREATED_BY = db.Column(db.String(20))
    CREATED_DATE = db.Column(db.Date)
def user_to_dict(user):
    return OrderedDict(
        USER_ID = user.USER_ID,
        USERNAME = user.USERNAME,
        CREATED_BY = user.CREATED_BY,
        CREATED_DATE = user.CREATED_DATE
@app.route('/users')
def list_users():
    users = User.query.all()
    return jsonify(list(map(user_to_dict, users)))
@app.route('/users/<userid>')
def find_user(userid):
    user = User.query.get(userid)
    return jsonify(user_to_dict(user))
if __name__ == "__main__":
    app.run(debug=True)

在本例中,user_to_dict() 函数实现了将 user 对象转换为 dict,但这种写法是硬编码的,有多少个 Model 就要写多少个函数,所以,我们接下来考虑如何实现通用的代码。

对于 User 的实例,可以用 __dict__ 特殊属性获取实例的字段,为了通用化,将代码放在一个基类中:

class EntityBase(object):
    def to_json(self):
        fields = self.__dict__
        if "_sa_instance_state" in fields:
            del fields["_sa_instance_state"]
        return fields

然后在 Model 中通过多重继承,让 model 继承 EntitiBase 类,这样就不用改变每个 model 类的代码。为了方便叙述和学习,也给出第二种方法的完整代码:

from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
import os
from collections import OrderedDict
app = Flask(__name__)
# application configurations
app.config['SECURITY_KEY'] = 'you will never guess'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DB_URI']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['JSON_SORT_KEYS'] = False
db = SQLAlchemy(app)
class EntityBase(object):
    def to_json(self):
        fields = self.__dict__
        if "_sa_instance_state" in fields:
            del fields["_sa_instance_state"]
        return fields
class User(db.Model, EntityBase):
    __tablename__ = 'user'
    USER_ID = db.Column(db.Integer, primary_key=True)
    USERNAME = db.Column(db.String(20))
    CREATED_BY = db.Column(db.String(20))
    CREATED_DATE = db.Column(db.Date)
@app.route('/users')
def list_users():
    users = User.query.all()
    users_output = []
    for user in users:
        users_output.append(user.to_json())
    return jsonify(users_output)
@app.route('/users/<userid>')
def find_user(userid):
    user = User.query.get(userid)
    return jsonify(user.to_json())
if __name__ == "__main__":
    app.run(debug=True)

如果有多个表,并且有关联,以上方法需要更多的手工代码。比较好的方法是使用第三方模块:Flask-Marshmallow,这个也是我想推荐的方法。通过 pip 安装 Flask-Marshmallow 模块后,我们需要定义一个 UserSchema 类,并且确定 UserSchema 对应到 User,如下面的代码:

from flask_marshmallow import Marshmallow
ma = Marshmallow(app)
class UserSchema(ma.ModelSchema):
    class Meta:
        model = User

然后在路由中,可以方便的通过 dump() 方法转换为 dict。

@app.route('/users')
def list_users():
    users = User.query.all()
    user_schema = UserSchema(many=True)
    user_data = user_schema.dump(users)
    return jsonify(user_data)
@app.route('/users/<userid>')
def find_user(userid):
    user = User.query.get(userid)
    user_schema = UserSchema()
    user_data = user_schema.dump(user)
    return jsonify(user_data)

完整代码如下:

from flask import Flask, jsonify
from flask_marshmallow import Marshmallow
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
# application configurations
app.config['SECURITY_KEY'] = 'you will never guess'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DB_URI']
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['JSON_SORT_KEYS'] = False
db = SQLAlchemy(app)
ma = Marshmallow(app)
class User(db.Model):
    __tablename__ = 'user'
    USER_ID = db.Column(db.Integer, primary_key=True)
    USERNAME = db.Column(db.String(20), nullable=False)
    CREATED_BY = db.Column(db.String(20), nullable=False)
    CREATED_DATE = db.Column(db.Date, nullable=False)
class UserSchema(ma.ModelSchema):
    class Meta:
        model = User
@app.route('/users')
def list_users():
    users = User.query.all()
    user_schema = UserSchema(many=True)
    user_data = user_schema.dump(users).data
    return jsonify(user_data)
@app.route('/users/<userid>')
def find_user(userid):
    user = User.query.get(userid)
    user_schema = UserSchema()
    user_data = user_schema.dump(user).data
    return jsonify(user_data)
if __name__ == "__main__":
    app.run(debug=True)

源码放在 github 上。

在 Flask 实现 Rest API (02) - 查询结果转换为 json 字符串 这篇文章中,介绍了基于原生 CRUD 将查询结果转为 json 格式的方法。本篇接着介绍使用 Flask-SqlAlchemy 时,如何将查询结果转换为 json 格式。过程是先将查询的结果转为 dict/list,然后将 dict/list 转为 json,dict/list 转 json 是 Python ...
我觉得最简单明了的就是在模型定义的时候给个序列化的方法,想要哪个或想变成其他格式都很方便,就是要多写一些代码 继承改写 flask 里面的 JSONEncoder,这个方法好像很好,但如何去除自己不想要的变量,不知道有没有可以参考的源代码,求解? 也有说用 Marshmallow,看起来还要定义很多东西,不知道用的人多不多? 方法一:见grey li书中例子:https://github.com/...
简单而快速地开始两个步骤。 .1。 导入FlaskSerializeMixin mixin并将其添加到模型中: from flask_serialize import FlaskSerialize # create a flask-serialize mixin instance from # the factory method `FlaskSerialize` fs_mixin = FlaskSerialize ( db ) class Item ( db . Model , fs_mixin ): id = db . Column ( db . Integer , primary_key = Tr ##################################################### logging.info("========================= select sql ==============================") from sqlalchemy.dialects import postgresql rt...
因为不关心前台页面的开发,前台工程师给我提供了一份json样式。让我实现,然后给出了筛选条件。还是接着上篇文章,将ORM这块仔细写写。这篇文章也将关于flask-sqlalchemy的总结,我会把用户遇到的格式问题都总结在这里面。我写博客的原则,用过什么写什么,没涉及的也不瞎写了。 首先看前台工程师给我提供的json返回格式样例。大概就是以song为对象的list,里面有嵌着多对多关...
__tablename__ = 'user' uid = Column(Integer, primary_key=True) username = Column(String(15), nullable=False, unique=True) password_hash = ...
Flask REST API 使用Flask在python中内置的简单REST API。 它支持get , put , patch和delete的请求。 该API从Animal Crossing村民的本地SQL-Alchemy数据库中提取数据数据集包括村民的姓名,种类,个性和报价。 请求“ / villager / name”以json格式返回村民的信息。 运行应用程序 在命令行中,导航到main.py所在的文件夹。 然后输入: # run the flask application python main.py 使用网络浏览器查看运行在的应用程序。 响应示例: 运行test.py以查看所有受支持的请求。 当主应用程序仍在运行时,在新的命令行上键入: # test all the supported requests python test.py 您可以找到以下字
以下是在进行微信小程序开发过程中积累的经验,有不足之处请指教。谢谢。 微信小程序是基于微信自己的框架。无法像其它语言一样直接访问数据库,只能通过以https方式提交数据到后台,后台写一个操作本地数据库的服务端web应用程序,提供https接口让小程序调用。 1. 首先看微信小程序端是如何像后台数据库接口应用发起请求的。 在微信小程序的js文件中的某个事件中,通常是按钮事件,发起...
本文主要介绍Python中,使用SQLAlchemy查询出来结果,通过json.dumps()方法转换JSON字符串方法,以及相关示例代码。 1、使用实体类转换JSON字符串 使用定义相应类型的实体类,将数据库数据类对象换成实体类对象,之后再进行转换: from dataclasses import dataclass from datetime import datetime from flask import Flask, jsonify from flask_sqlalchemy imp
class AlchemyEncoder(json.JSONEncoder):     def default(self, obj):         if isinstance(obj.__class__, DeclarativeMeta):             # an SQLAlchemy class             fields = {} app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://user:password@localhost/db_name' db = SQLAlchemy(app) class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), nullable=False) age = db.Column(db.Integer, nullable=False) def to_dict(self): return {'id': self.id, 'name': self.name, 'age': self.age} @app.route('/users') def get_users(): users = User.query.all() users_dict = [user.to_dict() for user in users] return jsonify(users_dict) if __name__ == '__main__': app.run(debug=True) 上述代码中,我们定义了一个 `User` 模型,使用 `query.all()` 获取所有用户对象,并将其转换为字典格式的列表,最后使用 `jsonify()` 将其转换JSON 格式返回给客户端。 在字典格式转换中,我们还定义了一个 `to_dict()` 方法,用于将模型对象转换为字典格式,方便后续的 JSON 格式转换
sap_fico_low: 你好,以下问题是不是只能联系Basis解决? 没有为逻辑文件名称 FI_COPY_COMPANY_CODE_DATA_FOR_GENERAL_LEDGER_0X 配置物理路径 消息编号 SG813 没有为逻辑文件名配置任何物理路径,或逻辑路径为空。 无法验证文件。 请联系系统管理员正确配置逻辑文件名。 系统管理过程 在事务 FILE 中,在逻辑文件名配置中插入逻辑路径。如果已存在逻辑路径,检查是否已针对逻辑路径配置物理路径。 pandas DataFrame 导出到Excel格式美化 CSDN-Ada助手: 不知道 Python入门 技能树是否可以帮到你:https://edu.csdn.net/skill/python?utm_source=AI_act_python ABAP DOI详解(2) auhsojj_cn: 想咨询一下博主,为什么嵌入参数都设置了,但是excel还是独立窗口显示的呢