將mongoDB資料轉化為json---Python實現
前提背景
我們知道,mongoDB資料庫表中的一條資料(document)在呈現的時候,很像json。在平時的使用中,有時候會有這樣的需求:我們需要將資料庫中的資料讀出來,並將其傳送(例如ajax請求)到前端頁面去解析呈現。顯然此時,為了更容易解析,我們需要將資料轉為為json形式。
mongoengine作為一個操作mongoDB資料庫的python解析庫,其在將表中的資料轉化為json形式時,雖然有to_json方法,但是轉化的json資料是不完全,冗餘的,包括“id”值多層巢狀,以及datetime型別的時間比標準時間多8個小時等(這是在我做的時候遇到的一個坑,因為插入到mongoDB中的date為ISODate型別的)。總之是有多種問題。因此,只能自己找方法來解決。
問題解決
通過看網上Stack Overflow的各種問題,大多數都是自己寫json轉化程式碼來實現的。這裡我也是一樣,通過查閱文件,mongoengine有一個to_mongo方法,可以將mongoDB的資料(document)轉化為SON型別的資料。關於SON型別,看官方的解釋
SON data.
A subclass of dict that maintains ordering of keys and provides a
few extra niceties for dealing with SON. SON provides an API
similar to collections.OrderedDict from Python 2.7+.
它是Python中”字典“的一個子類,也就是說它具備字典的特性了。這裡發現一個坑,若是直接遍歷SON型別資料當資料庫的文件中有嵌入文件時,嵌入文件的欄位是取不到的,這裡我採取先轉化為字典,再去遍歷。具體程式碼如下:
import datetime
import json
from mongoengine.base import BaseDocument
# 使json能夠轉化datetime物件
class DateEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime. datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, datetime.date):
return obj.strftime("%Y-%m-%d")
else:
return json.JSONEncoder.default(self, obj)
# 將 MongoDB 的 document轉化為json形式
def convertMongoToJson(o):
def convert(dic_data):
# 對於引用的Id和該條資料的Id,這裡都是ObjectId型別的
from bson import ObjectId
# 字典遍歷
for key, value in dic_data.items():
# 如果是列表,則遞迴將值清洗
if isinstance(value, list):
for l in value:
convert(l)
else:
if isinstance(value, ObjectId):
dic_data[key] = str(dic_data.pop(key))
return dic_data
ret = {}
# 判斷其是否為Document
if isinstance(o, BaseDocument):
"""
轉化為son形式,son的說明,摘自官方
SON data.
A subclass of dict that maintains ordering of keys and provides a
few extra niceties for dealing with SON. SON provides an API
similar to collections.OrderedDict from Python 2.7+.
"""
data = o.to_mongo()
# 轉化為字典
data = data.to_dict()
ret = convert(data)
# 將資料轉化為json格式, 因json不能直接處理datetime型別的資料,故需要區分處理
ret = json.dumps(ret, cls=DateEncoder)
return ret
若有任何問題,可一起討論哈。