標籤:_id nbsp 函數 eal 自動 tle .post 格式 error:
MongoDB介紹
MongoDB是一個面向文檔的,開來源資料庫程式,它平台無關。MongoDB像其他一些NoSQL資料庫(但不是全部!)使用JSON結構的文檔儲存資料。這是使得資料非常靈活,不需要的Schema。
一些比較重要的特點是:
- 支援多種標準查詢類型,比如matching()、comparison (, )或者Regex;
- 可以儲存幾乎任何類型的資料,無論是結構化,部分結構化,甚至是多態;
- 要擴充和處理更多查詢,只需添加更多的機器;
- 它是高度靈活和敏捷,讓您能夠快速開發應用程式;
- 作為基於文檔的資料庫意味著您可以在單個文檔中儲存有關您的模型的所有資訊;
- 您可以隨時更改資料庫的Schema;
- 許多關係型資料庫的功能也可以在MongoDB使用(如索引)。
在運行方面,MongoDB中有相當多的功能在其他資料庫中是沒有的:
- 無論您需要獨立伺服器還是完整的獨立伺服器叢集,MongoDB都可以根據需要進行擴充;
- MongoDB還通過在各個分區上自動移動資料來提供負載平衡支援;
- 它具有自動容錯移轉支援,如果主伺服器Down掉,新的主伺服器將自動啟動並運行;
- MongoDB的管理服務(MMS)可以用於監控和備份MongoDB的基礎設施服務;
- 不像關聯式資料庫,由於記憶體對應檔,你將節省相當多的RAM。
雖然起初MongoDB似乎是解決我們許多問題的資料庫,但它不是沒有缺點的。MongoDB的一個常見缺點是缺少對ACID事務的支援,MongoDB在特定情境下支援ACID事務,但不是在所有情況。在單文檔層級,支援ACID事務(這是大多數事務發生的地方)。但是,由於MongoDB的分布式性質,不支援處理多個文檔的事務。
MongoDB還缺少對自然join查詢支援。在MongoDB看來:文檔意在包羅永珍,這意味著,一般來說,它們不需要參考其他文檔。在現實世界中,這並不總是有效,因為我們使用的資料是關係性的。因此,許多人認為MongoDB應該被用作一個SQL資料庫的補充資料庫,但是當你使用MongoDB是,你會發現這是錯誤的。
PyMongo
由MongoDB開發人員發布的官方驅動程式PyMongo(https://pypi.python.org/pypi/pymongo/),這裡通過一些例子介紹,但你也應該查看完整的文檔(https://api.mongodb.com/python/current/)。
1、pip方式安裝
pip install pymongo==3.4.0
2、模組引用
import pymongo
3、建立串連
使用MongoClient對象建立串連:from pymongo import MongoClientclient = MongoClient()使用上面的程式碼片段,將建立串連到預設主控件(localhost)和連接埠(27017)。您還可以指定主機和/或使用連接埠:client = MongoClient(‘localhost‘, 27017)或者使用MongoURl格式:client = MongoClient(‘mongodb://localhost:27017‘)
4、訪問資料庫
一旦你有一個串連的MongoClient執行個體,你可以在Mongo伺服器中訪問任何資料庫。如果要訪問一個資料庫,你可以當作屬性一樣訪問:db = client.pymongo_test或者你也可以使用字典形式的訪問:db = client[‘pymongo_test‘]
如果您的指定資料庫已建立,實際上並不重要。通過指定此資料庫名稱並將資料儲存到其中,您將自動建立資料庫。
5、插入文檔
在資料庫中儲存資料,就如同調用只是兩行代碼一樣容易。第一行指定你將使用哪個集合。在MongoDB中術語中,一個集合是在資料庫中儲存在一起的一組文檔(相當於SQL的表)。集合和文檔類似於SQL表和行。第二行是使用集合插入資料insert_one()的方法:
posts = db.postspost_data = { ‘title‘: ‘Python and MongoDB‘, ‘content‘: ‘PyMongo is fun, you guys‘, ‘author‘: ‘Scott‘}result = posts.insert_one(post_data)print(‘One post: {0}‘.format(result.inserted_id))
我們甚至可以使用insert_one()同時插入很多文檔,如果你有很多的文檔添加到資料庫中,可以使用方法insert_many()。此方法接受一個list參數:
post_1 = { ‘title‘: ‘Python and MongoDB‘, ‘content‘: ‘PyMongo is fun, you guys‘, ‘author‘: ‘Scott‘}post_2 = { ‘title‘: ‘Virtual Environments‘, ‘content‘: ‘Use virtual environments, you guys‘, ‘author‘: ‘Scott‘}post_3 = { ‘title‘: ‘Learning Python‘, ‘content‘: ‘Learn Python, it is easy‘, ‘author‘: ‘Bill‘}new_result = posts.insert_many([post_1, post_2, post_3])print(‘Multiple posts: {0}‘.format(new_result.inserted_ids))
看到類似輸出:
One post: 584d947dea542a13e9ec7ae6Multiple posts: [ ObjectId(‘584d947dea542a13e9ec7ae7‘), ObjectId(‘584d947dea542a13e9ec7ae8‘), ObjectId(‘584d947dea542a13e9ec7ae9‘)]
注意: 不要擔心,你和上面顯示不一樣。它們是在插入資料時,由Unix的紀元,機器標識符和其他唯一資料群組成的動態標識。
6、檢索文檔
檢索文檔可以使用find_one()方法,比如要找到author為Bill的記錄:
bills_post = posts.find_one({‘author‘: ‘Bill‘})print(bills_post)運行結果:{ ‘author‘: ‘Bill‘, ‘title‘: ‘Learning Python‘, ‘content‘: ‘Learn Python, it is easy‘, ‘_id‘: ObjectId(‘584c4afdea542a766d254241‘)}
這篇文章的ObjectId是設定的_id,這是以後可以使用唯一標識。如果需要查詢多條記錄可以使用find()方法:
scotts_posts = posts.find({‘author‘: ‘Scott‘})print(scotts_posts)結果:<pymongo.cursor.Cursor object at 0x109852f98>
他的主要區別在於文檔資料不是作為數組直接返回給我們。相反,我們得到一個遊標對象的執行個體。這Cursor是一個包含相當多的輔助方法,以協助您處理資料的迭代對象。要獲得每個文檔,只需遍曆結果:
for post in scotts_posts: print(post)
MongoEngine
雖然PyMongo是非常容易使用,總體上是一個偉大的輪子,但是許多項目使用它都可能太低水平。簡而言之,你必須編寫很多自己的代碼來持續地儲存,檢索和刪除對象。PyMongo之上提供了一個更高的抽象一個庫是MongoEngine。MongoEngine是一個對象文檔映射器(ODM),它大致相當於一個基於SQL的對象關係映射器(ORM)。MongoEngine提供的抽象是基於類的,所以你建立的所有模型都是類。雖然有相當多的Python的庫可以協助您使用MongoDB,MongoEngine是一個更好的,因為它有一個很好的組合的功能,靈活性和社區支援。
使用者指南: http://docs.mongoengine.org/guide/index.html
1、pip方式安裝
pip install mongoengine==0.10.7
2、串連
from mongoengine import *connect(‘mongoengine_test‘, host=‘localhost‘, port=27017)
備忘:和pymongo不同。MongoEngine需要制定資料庫名稱。
3、定義文檔
建立文檔之前,需要定義文檔中要存放資料的欄位。與許多其他ORM類似,我們將通過繼承Document類,並提供我們想要的資料類型來做到這一點:
import datetimeclass Post(Document): title = StringField(required=True, max_length=200) content = StringField(required=True) author = StringField(required=True, max_length=50) published = DateTimeField(default=datetime.datetime.now)
在這個簡單的模型中,我們已經告訴MongoEngine,我們的Post執行個體有title、content、author、published。現在Document對象可以使用該資訊來驗證我們提供它的資料。
因此,如果我們試圖儲存Post的中沒有title那麼它會拋出一個Exception,讓我們知道。我們甚至可以進一步利用這個並添加更多的限制:
- required:設定必須;
- default:如果沒有其他值給出使用指定的預設值
- unique:確保集合中沒有其他document有此欄位的值相同
- choices:確保該欄位的值等於數組中的給定值之一
4、儲存文檔
將文檔儲存到資料庫中,我們將使用save()的方法。如果文檔中的資料庫已經存在,則所有的更改將在原子水平上對現有的文檔進行。如果它不存在,但是,那麼它會被建立。
這裡是建立和儲存一個文檔的例子:
post_1 = Post( title=‘Sample Post‘, content=‘Some engaging content‘, author=‘Scott‘)post_1.save() # This will perform an insertprint(post_1.title)post_1.title = ‘A Better Post Title‘post_1.save() # This will perform an atomic edit on "title"print(post_1.title)
調用save()的時候需要注意幾點:
- PyMongo將在您調用.save()時執行驗證,這意味著它將根據您在類中聲明的模式檢查要儲存的資料,如果違反模式(或約束),則拋出異常並且不儲存資料;
- 由於Mongo不支援真正的事務,因此沒有辦法像在SQL資料庫中那樣“復原”.save()調用。
當你儲存的資料沒有title時:
post_2 = Post(content=‘Content goes here‘, author=‘Michael‘)post_2.save()raise ValidationError(message, errors=errors)mongoengine.errors.ValidationError:ValidationError (Post:None) (Field is required: [‘title‘])
5、向對象的特性
使用MongoEngine是物件導向的,你也可以添加方法到你的子類文檔。例如下面的樣本,其中函數用於修改預設查詢集(返回集合的所有對象)。通過使用它,我們可以對類應用預設過濾器,並只擷取所需的對象
class Post(Document): title = StringField() published = BooleanField() @queryset_manager def live_posts(clazz, queryset): return queryset.filter(published=True)
6、關聯其他文檔
你還可以使用ReferenceField對象來建立從一個文檔到另一個文檔的引用。MongoEngine在訪問時自動惰性處理引用。
class Author(Document): name = StringField()class Post(Document): author = ReferenceField(Author)Post.objects.first().author.name
在上面的代碼中,使用文檔”外鍵”,我們可以很容易地找到第一篇文章的作者。其實還有比這裡介紹的更多的欄位類(和參數),所以一定要查看文檔欄位更多資訊。
參考部落格:https://realpython.com/blog/python/introduction-to-mongodb-and-python/
https://my.oschina.net/jhao104/blog/812002
Python MongoDB使用