遇到的问题:
通过sqlalchemy查询的结果,如果直接通过jsonify函数转为json会报错:
TypeError: Object of type 'Comment' is not JSON serializable
网上有各种方案,例如增加一个AlchemyEncoder类来专门处理,但是本人试过都不行,以下方案才是正解:
1. 需要在模型类中增加to_json函数:
class Comment(db.Model):
__tablename__ = 't_comment'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
content = db.Column(db.Text, nullable=False)
create_time = db.Column(db.DateTime, nullable=False, default=datetime.now)
author_id = db.Column(db.Integer, db.ForeignKey('t_user.id'))
question_id = db.Column(db.Integer, db.ForeignKey('t_question.id'))
author = db.relationship('User', backref=db.backref('comments'))
question = db.relationship('Question', backref=db.backref('comments', order_by=create_time.desc()))
def to_json(self):
dict = self.__dict__
if "_sa_instance_state" in dict:
del dict["_sa_instance_state"]
return dict
2. 将查询的结果,一次通过to_json方法放到数组中,在通过jsonify函数返回到前台:
# rest api接口,并将查询结果转化为json
@app.route('/comments', methods=['GET'])
def comments():
comments = db.session.query(Comment).all()
result = []
for comment in comments:
result.append(comment.to_json())
return jsonify(result), 200
SQLAlchemy
-
JSON
API
旨在实现
JSON
API
规范,并使其尽可能易于使用和实现。
pip install
sqlalchemy
-
json
api
快速使用Flask-
SQLAlchemy
# Assuming Flask
SQLAlchemy
is db and your Flask app is app:
from
sqlalchemy
_
json
api
import Flask
JSON
API
api
= Flask
JSON
API
( app , db )
# Or, for factory-style applications
api
= Flask
JSON
API
()
api
. init_app ( app , db )
无需烧瓶即可快速使用
# Assuming declarative base is
最近,给自己开发的软件平台开发第三方调用的
API
,如果
返回
结果集是
json
格式,其他语言开发就相对方便一些,网上找了好多资料没有找到特别合适的,最后下决心根据网上的资料改变自己写一个通用的。
此方法,主要应用场景是,Python
数据库
框架
sqlalchemy
查询
结果,转化成
json
格式。
# -*- coding: utf-8 -*-
import os
import
json
在前后端分离项目中,经常需要把ORM模型转化为字典,再将字典转化为
JSON
格式的字符串。在遇到
sqlalchemy
_serializer之前,我都是通过类似Java中的反射原理,获取当前ORM模型的所有字段,然后写一个to_dict方法来将字段以及他的值封装成字典。这种做法虽然一定程度上方便了开发,但也是带着枷锁跳舞,存在以下几个弊端:无法优雅的排除不需要序列化的字段。无法优雅的序列化多表之间的关系。
今天对clubot进行了升级, 但是导入
数据
后中文乱码, 一开是找资料说是在创建引擎的时候添加编码信息:
engine = create_engine(mysql://root:@localhost:3306/clubot?charset=utf8)
但是这并不行, 然后查看表信息:
> show create table clubot_members;
clubot_members | CREATE TABLE `clubot_members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) DEFAUL
快速的
查询
构建器,用于
返回
与兼容的结果。 目前仅支持 。
速度对于
JSON
API
至关重要。 与直接从
数据库
返回
JSON
相比,在获取对象并在Python服务器上对其进行序列化要慢一个数量级。 这是因为
当序列化发生在Python端时,使用单个
查询
很难或不可能获取复杂的对象结构。 可以通过
数据库
中的单个
查询
返回
任何与
JSON
API
兼容的对象结构。
SQLAlchemy
对象内存不足。
与其直接从
数据库
作为
JSON
直接
返回
数据
,不如将其首先转换为Python
数据
类型,然后再序列化回
JSON
。
通过遵循此逻辑,直接从
数据库
返回
JSON
似乎很容易。 但是
查询
很难编写。 幸运的是,这是
SQLAlchemy
-
JSON
-
API
拯救这一天的地方。 因此,与其写这样的东西:
SELECT row_to_
json
(main_
json
_query.
SAFRS:Python Open
API
和
JSON
:
API
框架
SAFRS是对于s QL甲lchemy˚Flask-řestful小号wagger的缩写。 这个框架的目的是帮助python开发人员为
sqlalchemy
数据库
对象和关系创建一个自文档化的
JSON
API
。 这些对象可以序列化为
JSON
,并且可以通过
JSON
API
创建,检索,更新和删除。 (可选)可以使用
JSON
公开和调用自定义资源对象方法。 可以在代码注释中以yaml语法提供类和方法的描述以及示例。 描述被解析并显示在swagger Web界面中。
结果是易于使用的和兼容的
API
实现。
可以使用 ,其中许多基本功能都
用
sqlalchemy
做关联
查询
时发现不支持用自带的
json
属性得到
json
字符串,写了一个方法利用dir来遍历属性,转成
json
DBSession = sessionmaker(bind=engine)
session = DBSession()
records = session.query(A.name, B.name).filter(A.aid == B.aid).all()
session.close()
def convert_to_
json
(inst):
d = dict()
继承
json
.
JSON
Encoder
实现一个针对
sqlalchemy
返回
类型的处理方式。
sqlalchemy
的
返回
类型有大都有两种,一种是Model对象,一种是Query集合(只
查询
部分字段)。
针对这两种
返回
结果,都是来自同一中类型
sqlalchemy
.orm.query.Query
所以针对Query做相应处理,让他
返回
一个dict
class AlchemyJ...
因为不关心前台页面的开发,前台工程师给我提供了一份
json
样式。让我实现,然后给出了筛选条件。还是接着上篇文章,将ORM这块仔细写写。这篇文章也将关于flask-
sqlalchemy
的总结,我会把用户遇到的格式问题都总结在这里面。我写博客的原则,用过什么写什么,没涉及的也不瞎写了。
首先看前台工程师给我提供的
json
返回
格式样例。大概就是以song为对象的list,里面有嵌着多对多关...
相信大家在网上搜一下, 有很多我标题里面问题的处理办法, 我这边说下我最终的解决办法, 亲测可用, 也算是对我解决这个问题的心路历程的一个记录, 唉, 果然, 学习一个新东西, 每一步都是挑战:
我的环境: python3.7, Flask-
SQLAlchemy
2.4.4
1. 我先是查到了这类资料: 增加一个AlchemyEncoder类来专门处理
我是想的我只是做几个小
接口
, 不用专门弄个类吧, 我就没试验这类方法了,
2. 我搜着搜着, 找到这样一篇博客:
sqlalchemy
查询
结果
转为
j
则为User类型的集合,无法直接return给前端,需要进行格式化。网上一般会推荐使用
json
.dump()或者
json
ify()来序列化
数据
,但对于
sqlalchemy
的对象并不适用。注意:根据官网文档,已经不推荐使用下面的方法来
查询
数据
。