sqlalchemy和flask-sqlalchemy查詢結果轉json

Flask-RESTful 有一個專門作這個的東西,叫 marshal_with,
具體介紹在這裏:http://flask-restful.readthedocs.org/en/latest/fields.html
我通常都是用它來格式化返回值php

marshal_with 實際作的只是把數據庫對象轉換成 dict 或者 list of dict
把 dict 轉換成 json 是由 Flask-RESTful 自動完成的,不用手動調用 jsonifyhtml


若是你以爲上面的方法太麻煩,這裏還有一個工具,對 Flask-RESTful 進行了擴展,其中就包括簡化 marshal_with 操做(marshal.py),以及增強 json 轉換功能(extend_json.py, json_encoder_manager.py)。git

你能夠參考下它裏面的代碼
(不過這個工具是針對 SQLAlchemy 的,對於 Peewee 可能須要修改一下)github

https://github.com/anjianshi/flask-restful-extendsql

 

 

  以前爲了學習Python,試着拿Flask做框架搞小網站,感受還不錯,基本就拋棄了PHP。前段時間作了一個微信小程序,想着yii框架拿來寫幾十個小接口是否是浪費了,就繼續用flask寫api了,哪想到填坑無數啊。數據庫

  Python的ORM框架就屬Sqlalchemy牛逼,網上資料也多,想着和yii裏面應該差很少,就拿來用了。次日萬萬沒想到,php裏面簡單的一句asArray就能解決的問題,flask_sqlalchemy竟然沒有解決方案,查詢的結果對象沒法直接JSON序列化。這期間從南到北地找,大部分解決方案都是作一個JSON.dumps的Encoder方法,來轉化restult對象,無心中看見https://www.cnblogs.com/wancy86/p/6421792.html 這個帖子,說queryresult對象加入了json屬性,欣喜萬分,搞了一夜也沒找到這個方法。json

  原文連接:http://www.javashuo.com/article/p-qmqtpnee-gx.htmlflask

 


 

咳咳,正文:  小程序

  網上的方法主要問題在於只能處理result對象或model對象之一,當查詢某個表所有字段時,如segmentfault

1 db.session.query(User).filter().all()

  其返回User這個類的對象列表,而查詢某些字段或者多表鏈接時,如:

 1 db.session.query(User.UserID,User.UserName).filter().all() 

  其返回result對象的列表,這兩種狀況下,對象的屬性不一樣,致使不少狀況下只能適應一種返回。今天趁閒着沒事,把兩種狀況的查詢結果轉dict做了一下整理,封裝爲一個queryToDict函數,並同時支持all()返回的列表和first()返回的單個對象結果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

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 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 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 in results]

    #這裏r爲一個字典,對象傳遞直接改變字典屬性

    for 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 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 ""

1

dit = dict((g[0],g[1]) for in gen)相關代碼也是以前查找資料得到,如今找不到出處了,做者能夠聯繫我。

1

滾去學雅思了,代碼寫得較快,歡迎指出bug

參考資源:

[1] https://stackoverflow.com/questions/5022066/how-to-serialize-sqlalchemy-result-to-json

[2] https://segmentfault.com/q/1010000007459402/a-1020000007460322

我就是我,吃瓜的瓜

 

http://www.javashuo.com/article/p-qmqtpnee-gx.html

相關文章
相關標籤/搜索