以前为了学习Python,试着拿Flask做框架搞小网站,感受还不错,基本就抛弃了PHP。前段时间作了一个微信小程序,想着yii框架拿来写几十个小接口是否是浪费了,就继续用flask写api了,哪想到填坑无数啊。php
Python的ORM框架就属Sqlalchemy牛逼,网上资料也多,想着和yii里面应该差很少,就拿来用了。次日万万没想到,php里面简单的一句asArray就能解决的问题,flask_sqlalchemy竟然没有解决方案,查询的结果对象没法直接JSON序列化。这期间从南到北地找,大部分解决方案都是作一个JSON.dumps的Encoder方法,来转化restult对象,无心中看见https://www.cnblogs.com/wancy86/p/6421792.html 这个帖子,说queryresult对象加入了json属性,欣喜万分,搞了一夜也没找到这个方法。html
原文连接:http://www.javashuo.com/article/p-qmqtpnee-gx.html
python
咳咳,正文: sql
网上的方法主要问题在于只能处理result对象或model对象之一,当查询某个表所有字段时,如json
1 db.session.query(User).filter().all()
其返回User这个类的对象列表,而查询某些字段或者多表链接时,如:flask
1 db.session.query(User.UserID,User.UserName).filter().all() 小程序
其返回result对象的列表,这两种状况下,对象的属性不一样,致使不少状况下只能适应一种返回。今天趁闲着没事,把两种状况的查询结果转dict做了一下整理,封装为一个queryToDict函数,并同时支持all()返回的列表和first()返回的单个对象结果:segmentfault
from datetime import datetime as cdatetime #有时候会返回datatime类型 from datetime import date,time from flask_sqlalchemy import Model from sqlalchemy.orm.query import Query from sqlalchemy import DateTime,Numeric,Date,Time #有时又是DateTime def queryToDict(models): if(isinstance(models,list)): if(isinstance(models[0],Model)): lst = [] for model in models: gen = model_to_dict(model) dit = dict((g[0],g[1]) for g in gen) lst.append(dit) return lst else: res = result_to_dict(models) return res else: if (isinstance(models, Model)): gen = model_to_dict(models) dit = dict((g[0],g[1]) for g in gen) return dit else: res = dict(zip(models.keys(), models)) find_datetime(res) return res #当结果为result对象列表时,result有key()方法 def result_to_dict(results): res = [dict(zip(r.keys(), r)) for r in results] #这里r为一个字典,对象传递直接改变字典属性 for r in res: find_datetime(r) return res def model_to_dict(model): #这段来自于参考资源 for col in model.__table__.columns: if isinstance(col.type, DateTime): value = convert_datetime(getattr(model, col.name)) elif isinstance(col.type, Numeric): value = float(getattr(model, col.name)) else: value = getattr(model, col.name) yield (col.name, value) def find_datetime(value): for v in value: if (isinstance(value[v], cdatetime)): value[v] = convert_datetime(value[v]) #这里原理相似,修改的字典对象,不用返回便可修改 def convert_datetime(value): if value: if(isinstance(value,(cdatetime,DateTime))): return value.strftime("%Y-%m-%d %H:%M:%S") elif(isinstance(value,(date,Date))): return value.strftime("%Y-%m-%d") elif(isinstance(value,(Time,time))): return value.strftime("%H:%M:%S") else: return ""
dit = dict((g[0],g[1]) for g in gen)相关代码也是以前查找资料得到,如今找不到出处了,做者能够联系我。
滚去学雅思了,代码写得较快,欢迎指出bug
参考资源:微信小程序
[1] https://stackoverflow.com/questions/5022066/how-to-serialize-sqlalchemy-result-to-jsonapi
[2] https://segmentfault.com/q/1010000007459402/a-1020000007460322