一文說通MongoDB via Python操作
Python並不僅僅是一個做Machine Learning的語言。
說到Python,一般都會感覺它關聯著ML,如果不是做ML開發,就會覺得離自己很遠。而實際上,作為一門語言,Python在應用中跟別的語言沒什麼區別,甚至在某些時間,它的方便會讓人感覺很舒服。
試想一下,有個小需求,需要臨時改一些資料庫的資料。怎麼搞?直接寫資料庫指令碼?麻煩。開個IDE寫段程式碼?更麻煩。這時候,有Python就很爽了 --- 隨便開個Notepad或VIM,寫段程式碼,就搞定了。
很方便,有沒有?
所以,不管做什麼樣的開發,瞭解一點Python,還是有點意義的。
今天我們就整理一個知識點:Python操作MongoDB資料庫。
為了防止不提供原網址的轉載,特在這裡加上原文連結:https://www.cnblogs.com/tiger-wang/p/13216977.html
一、執行準備
首先,我們需要有Python3 。現在Python全線從v2轉為v3,如果還停留在v2的年代,不妨升一下級。
Python3的安裝不詳細說,官網在https://www.python.org。
檢查是否安裝Python3,可以用以下命令:
%python3--version
Python3.7.4
如果安裝了,會返回Python3的版本號。我裝的是3.7.4 。
Python操作MongoDB資料庫,需要PyMongo庫的支援。
%pipinstallpymongo
或者
%python3-mpipinstallpymongo
pip是Python全系的軟體包管理工具,類似於Ubuntu/Debian的apt、Centos的rpm、MacOS的brew。
新安裝的Python3,可能沒有pip命令。檢查一下:
%pip--version
同樣,如果有安裝,會返回pip的版本號。
如果沒有安裝,以下是命令:
%curlhttps://bootstrap.pypa.io/get-pip.py-oget-pip.py
%python3get-pip.py
也可以去pip官網自行查詢安裝。官網在https://pip.pypa.io/en/stable/
MongoDB也需要安裝好。安裝過程在文章15分鐘從零開始搭建支援10w+使用者的生產環境(二)裡有詳細的步驟,這兒略過。
這樣,我們就準備好了全部的執行環境。
二、操作MongoDB
1. 連線串
MongoDB的連線串,在所有開發語言中都是一樣的:
database_connection_uri="mongodb://localhost:27031/admin"
2. 連線資料庫
PyMongo提供了MongoClient
用來連線MongoDB,並初始化物件。
client=pymongo.MongoClient(database_connection_uri)
3. 開啟資料庫和資料集
db=client["Test"]
collection=db["TestCollection"]
這個例子中,資料庫叫Test
,資料集Collection叫TestCollection
。
到這兒,資料集已經正常開啟。
全部的程式碼如下:
#!/usr/local/binpython3
#-*-coding:UTF-8-*-
importpymongo
database_connection_uri="mongodb://localhost:27031/admin"
defmain():
client=pymongo.MongoClient(database_connection_uri)
db=client["Test"]
collection=db["TestCollection"]
print("Success!!!")
if__name__=='__main__':
main()
4. 建立索引
MongoDB中,索引很關鍵。一個好的索引可以讓上億級的資料集查詢在毫秒內出結果。
collection.create_index([("article_id",pymongo.ASCENDING)],background=True)
升序是pymongo.ASCENDING
,降序是pymongo.DESCENDING
。
看引數就知道,如果建立聯合索引,就把欄位名一個一個列出來:
collection.create_index([("article_id",pymongo.ASCENDING),("action_time",pymongo.DESCENDING)],background=True)
在MongoDB中,索引可以在任何時候建立。
5. 建立資料
PyMongo所有資料採用Json
資料。
Demo資料:
importdatetime
article1={
"article_id":1,
"title":"文章標題1",
"body":"文章內容1",
"action_time":datetime.datetime.utcnow()
}
直接呼叫collection
物件的insert
命令建立資料:
result=collection.insert(article1)
建立成功後,會返回該資料檔案的_id
值。
看一下全部程式碼:
defmain():
client=pymongo.MongoClient(database_connection_uri)
db=client["Test"]
collection=db["TestCollection"]
article1={
"article_id":1,
"title":"文章標題1",
"body":"文章內容1",
"action_time":datetime.datetime.utcnow()
}
result=collection.insert(article1)
print(result)
也可以一次建立多條檔案:
result=collection.insert([article1,article2])
注意那個中括號。
多條建立時,返回值result
也是個列表,裡面是所有建立記錄的_id
值。
此外,PyMongo還提供了另外兩個方法:insert_one
和insert_many
,對應建立一條資料和多條資料。
result=collection.insert_one(article1)
result=collection.insert_many([article1,article2])
這兩個方法返回值與insert
返回值略有不同,返回的是個物件。
insert_one
返回InsertOneResult
,InsertOneResult.inserted_id
才是_id
值。
insert_many
返回InsertManyResult
,InsertManyResult.inserted_ids
是_id
的列表。
6. 查詢資料
查詢資料有兩個方法:find_one
和find
。
先說find_one
,看名稱就知道,是查一條檔案資料,返回結果是一個字典型別的記錄。
result=collection.find_one({"article_id":1})
print(type(result))
print(result)
輸出結果:
<class'dict'>
{'_id':ObjectId('5efb1ecc7ca7cd50ed1150ed'),'article_id':1,'title':'文章標題1','body':'文章內容1','action_time':datetime.datetime(2020,6,30,11,15,24,97000)}
當然也可以使用_id
查詢:
frombson.objectidimportObjectId
result=collection.find_one({'_id':ObjectId('5efb1ecc7ca7cd50ed1150ed')})
find
方法,用來查詢多條資料。
results=collection.find({"title":{"$ne":""}})
print(type(results))
print(results)
forresultinresults:
print(result)
輸出結果:
<class'pymongo.cursor.Cursor'>
<pymongo.cursor.Cursorobjectat0x7f82c2cf7d50>
{'_id':ObjectId('5efb1ecc7ca7cd50ed1150ed'),'article_id':1,'title':'文章標題1','body':'文章內容1','action_time':datetime.datetime(2020,6,30,11,15,24,97000)}
{'_id':ObjectId('5efb1ecc7ca7cd50ed1150ee'),'article_id':2,'title':'文章標題2','body':'文章內容2','action_time':datetime.datetime(2020,6,30,11,15,24,97000)}
能看出,find
查詢的結果是一個遊標cursor
,指向返回的資料集合。資料可以迴圈讀出。
7. 結果統計
統計查詢結果有多少條資料,PyMongo提供了一個count
方法:
results=collection.find({"title":{"$ne":""}}).count()
或者查整個資料集的資料:
results=collection.find().count()
8. 排序查詢
排序也是一個方法,sort
:
results=collection.find({"title":{"$ne":""}}).sort("action_time",pymongo.ASCENDING)
升序是pymongo.ASCENDING
,降序是pymongo.DESCENDING
。
9. 偏移和限定
兩個用處不大不小的功能,通常在一起用,當然分開也沒關係。
results=collection.find({"title":{"$ne":""}}).sort("action_time",pymongo.DESCENDING).skip(1).limit(1)
limit
限定了結果集取多少條資料,而skip
則決定跳過多少條資料後去取。
在資料量不大的情況下,可以用來做分頁。而如果資料量很大,這種方式效率不高,更好的做法是記住前一個頁的最後一條資料的關鍵值,例如_id
,查詢時取條件大於這個值的資料。
10. 更新資料
PyMongo提供了兩個更新資料的方法:update_one
和update_many
。程式碼是這樣的:
filter={"article_id":1}
update={"$set":{"body":"新的文章內容"}}
result=collection.update_one(filter,update)
print(type(result))
返回一個物件UpdateResult
,裡麵包含更新結果的全部資訊。
注意:這兒有個不同於傳統SQL的地方,一定要注意。當更新的條件匹配到多條資料時,update_one
只會更新匹配到的資料集中第一條資料,update_many
可以更新匹配到的全部資料。所以,如果用update_one
,除非是你本意,一定要確定條件匹配到的資料唯一。
11. 刪除資料
也同樣有兩個方法:delete_one
和delete_many
。用法和更新相似:
filter={"article_id":1}
result=collection.delete_one(filter)
print(type(result))
同樣的,delete_one
也只會刪除匹配到的資料集中第一條資料。
11. 原子級處理
這是MongoDB中的一個特色操作,也是早期MongoDB的無奈之選。因為早期版本的MongoDB並不支援事務處理。而上面講到的更新和刪除,並不能保證併發情況下的資料安全。
MongoDB為瞭解決這個併發的資料問題,增加了三個原子級的處理,對應於PyMongo的三個方法:find_one_and_update
、find_one_and_replace
和find_one_and_delete
。
這三個方法,看名字就知道做什麼的。用法上,跟上面的更新和刪除一致,區別在於:這三個方法執行的時候,會通過資料鎖來保證資料修改在併發狀態下的一致性。當然,這個處理是有一定代價的,它要比上面說的更新和刪除慢一點,實測資料會慢5毫秒左右。
這三個方法應用挺廣的。比方我們需要生成一個自增量ID,就可以用find_one_and_update
來控制增量資料,因為他是原子級操作,所以併發也不會有重複的資料產生。
嗯,MongoDB從4.0開始,已經全面支援事務了。不過,這三個方法依然保留了下來。
12. 事務
這是一個新特性,需要資料庫4.0以上才支援。寫法上,跟傳統的事務沒什麼區別。
withclient.start_session()ass:
s.start_transaction()
filter={"article_id":1}
update={"$set":{"body":"新的文章內容"}}
result=collection.update_one(filter,update)
result=collection.delete_one(filter)
s.commit_transaction()
以上部分,就是Python操作MongoDB的全部內容。
最後,送大家一個彩蛋。
三、彩蛋
有時候,我們需要把寫好的Python程式給到別人來使用,可是,我們又不能讓別人也裝個Python。怎麼辦?
神器來了。
PyInstaller,官網在http://www.pyinstaller.org。
它的作用,是把您寫的Python程式,轉成各種作業系統下的可執行檔案。
PyInstaller安裝很簡單:
%pipinstallpyinstaller
使用更簡單:
%pyinstalleryour_code.py
經過一翻編譯,會生成幾個目錄。其中,dist
目錄下,就是編譯完成的可執行程式。當然,我們的Python程式會引用或依賴一些庫,而可愛的PyInstaller,也很貼心的把這些庫複製到了這個目錄中。
找到目錄中同名的可執行程式,例如這個例子中,將是your_code
,執行之,搞定。
(全文完)
本文的配套程式碼,在https://github.com/humornif/Demo-Code/tree/master/0016
微信公眾號:老王Plus 掃描二維碼,關注個人公眾號,可以第一時間得到最新的個人文章和內容推送 本文版權歸作者所有,轉載請保留此宣告和原文連結 |