Django操作NOSQL(MongoDB)數據庫

openkk 12年前發布 | 35K 次閱讀 MongoDB NoSQL數據庫

每一個Django工程師在接觸NOSQL數據庫的時候,肯定都會思考一個問題:在Django中不能像操作普通的關系型數據庫(以下簡稱RDB) 一樣,操作NOSQL數據庫嗎?當然可以,Django工程師幾乎不需要什么學習成本,就能使用NOSQL數據庫——因為有mongoengine這個模 塊。

MongoEngine由Python語言寫成,提供一個很類似Django ORM的API,本文介紹mongoengine的基本使用,主要是數據結構的定義和內聯表單的使用。

Install & Begin

需要安裝兩個模塊,pymongo和mongoengine

pip install -U mongoengine
pip install pymongo

現在我們以最快的方式利用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文件:

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幾乎一樣呢?

Philosophy

回頭說說代碼。docs.py中的語法很類似models.py,但兩者的用途完全不同。mongoengine是定義一個scheme,這些定義不會寫入到數據庫中。

在User中使用了三種Field,MongoDB是使用JSON格式存儲數據,所以寫入的值也可以是對象/數組/字典,mongoengine會 自動將Python數據格式轉換成JS數據格式,但必須按照之前的定義的Field類型來傳值。比如上例中的tags被定義為數組 (ListField),數組中的每個元素是字符(StringField),mongoengine只接受同樣類型的數據格式。

EmbeddedField

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來遍歷數據,查找、刪除也是類似的語法。

Afterword

mongoengine這種類似ORM的寫法提供了一個很好的過渡方式,但NOSQL數據庫畢竟不是構建于”關系”之上的,很多ORM的經驗并不適 用。其實操作NOSQL數據庫,對它進行增刪改查并不復雜,真正頭疼的是數據的建模,具體的業務邏輯,怎樣設計才能最大限度的發揮NOSQL數據庫的用途 等等一些列問題。mongoengine降低了Django工程師使用NOSQL數據庫的門檻,相信只要有更多的人參與其中,這類經驗會逐步豐富和完善 的。

文章出處:http://dmyz.org/archives/251

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!