以前爲了學習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