一文說通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
Python 3.7.4
如果安裝了,會返回Python3的版本號。我裝的是3.7.4 。
Python操作MongoDB資料庫,需要PyMongo庫的支援。
% pip install pymongo
或者
% python3 -m pip install pymongo
pip是Python全系的軟體包管理工具,類似於Ubuntu/Debian的apt、Centos的rpm、MacOS的brew。
新安裝的Python3,可能沒有pip命令。檢查一下:
% pip --version
同樣,如果有安裝,會返回pip的版本號。
如果沒有安裝,以下是命令:
% curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
% python3 get-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/bin python3
# -*- coding: UTF-8 -*-
import pymongo
database_connection_uri = "mongodb://localhost:27031/admin"
def main():
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資料:
import datetime
article1 = {
"article_id": 1,
"title": "文章標題1",
"body": "文章內容1",
"action_time": datetime.datetime.utcnow()
}
直接呼叫collection
物件的insert
命令建立資料:
result = collection.insert(article1)
建立成功後,會返回該資料文件的_id
值。
看一下全部程式碼:
def main():
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
查詢:
from bson.objectid import ObjectId
result = collection.find_one({'_id': ObjectId('5efb1ecc7ca7cd50ed1150ed')})
find
方法,用來查詢多條資料。
results = collection.find({"title": {"$ne":""}})
print(type(results))
print(results)
for result in results:
print(result)
輸出結果:
<class 'pymongo.cursor.Cursor'>
<pymongo.cursor.Cursor object at 0x7f82c2cf7d50>
{'_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以上才支援。寫法上,跟傳統的事務沒什麼區別。
with client.start_session() as s:
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安裝很簡單:
% pip install pyinstaller
使用更簡單:
% pyinstaller your_code.py
經過一翻編譯,會生成幾個目錄。其中,dist
目錄下,就是編譯完成的可執行程式。當然,我們的Python程式會引用或依賴一些庫,而可愛的PyInstaller,也很貼心的把這些庫複製到了這個目錄中。
找到目錄中同名的可執行程式,例如這個例子中,將是your_code
,執行之,搞定。
(全文完)
本文的配套程式碼,在https://github.com/humornif/Demo-Code/tree/master/0016
微信公眾號:老王Plus 掃描二維碼,關注個人公眾號,可以第一時間得到最新的個人文章和內容推送 本文版權歸作者所有,轉載請保留此宣告和原文連結 |