每個Django工程師在接觸NOSQL數據庫的時候,確定都會思考一個問題:在Django中不能像操做普通的關係型數據庫(如下簡稱RDB)同樣,操做NOSQL數據庫嗎?固然能夠,Django工程師幾乎不須要什麼學習成本,就能使用NOSQL數據庫——由於有mongoengine這個模塊。web
MongoEngine由Python語言寫成,提供一個很相似Django ORM的API,本文介紹mongoengine的基本使用,主要是數據結構的定義和內聯表單的使用。數據庫
須要安裝兩個模塊,pymongo和mongoenginedjango
pip install -U mongoengine
pip install pymongojson
如今咱們以最快的方式利用Django對MongoDB進行操做,請在電腦旁放置一個秒錶,理論上完成這些操做的時間不會超過3分鐘:數組
新建一個應用,其中新建一個docs.py文件,代碼以下:數據結構
from mongoengine import *
connect('test')
class User(Document):
username = StringField(required=True)
website = URLField()
tags = ListField(StringField(max_length=16))學習
而後編輯views.py文件:ui
from django.http import HttpResponse
from . import docs
def index(request):
user1 = docs.User(
username='Perchouli',
website='http://dmyz.org',
tags = ['Web','Django','JS']
)
user1.save()
Oid = user1.id
return HttpResponse(Oid)設計
最後,把視圖加到URL中,訪問這個視圖能夠看到返回的ObjectID,咱們已經實現了對NOSQL數據庫的寫入和查找了。是否是和Django ORM幾乎同樣呢?orm
回頭說說代碼。docs.py中的語法很相似models.py,但二者的用途徹底不一樣。mongoengine是定義一個scheme,這些定義不會寫入到數據庫中。
在User中使用了三種Field,MongoDB是使用JSON格式存儲數據,因此寫入的值也能夠是對象/數組/字典,mongoengine會自動將Python數據格式轉換成JS數據格式,但必須按照以前的定義的Field類型來傳值。好比上例中的tags被定義爲數組(ListField),數組中的每一個元素是字符(StringField),mongoengine只接受一樣類型的數據格式。
RDB對數據的組織是創建在「關係」之上的,好比咱們要存儲某個用戶的Profile,它與用戶ID是多對一的關係,在RDB中,一般要新建一張名爲Profile的表,其中包含UserID和Profile,每一條數據對應一個Profile的記錄,這種方式多少顯得有些笨拙。NOSQL的出現解決了這類問題,在NOSQL數據庫中使用內聯的方式,直接把Profile存在User下,調用User時就能夠得到Profile的數據了。
修改上例中的docs.py,增長Profile:
from mongoengine import *
connect('test')
#先定義名爲Profile的EmbeddedDocument
class Profile(EmbeddedDocument):
gender = StringField()
location = StringField()
class User(Document):
username = StringField(required=True)
website = URLField()
tags = ListField(StringField(max_length=16))
#添加到User
profile = EmbeddedDocumentField(Profile)
再修改views.py,爲了顯示區別這裏輸出一個JSON格式的字符串:
from django.http import HttpResponse
from . import docs
def index(request):
profile1 = docs.Profile(gender='male', location='Beijing')
user1 = docs.User(
username='Perchouli',
website='http://dmyz.org',
tags = ['Web','Django','JS'],
profile = profile1
)
user1.save()
user1_json = str(user1.to_mongo())
return HttpResponse(user1_json)
怎麼讀取profile中的gender和location?我不說你可能也想到了: user1.profile.gender。其餘的操做也同樣,都是用for來遍歷數據,查找、刪除也是相似的語法。
mongoengine這種相似ORM的寫法提供了一個很好的過渡方式,但NOSQL數據庫畢竟不是構建於」關係」之上的,不少ORM的經驗並不適用。其實操做NOSQL數據庫,對它進行增刪改查並不複雜,真正頭疼的是數據的建模,具體的業務邏輯,怎樣設計才能最大限度的發揮NOSQL數據庫的用途等等一些列問題。mongoengine下降了Django工程師使用NOSQL數據庫的門檻,相信只要有更多的人蔘與其中,這類經驗會逐步豐富和完善的。