一文說通MongoDB via Python操作
Python並不僅僅是一個做Machine Learning的語言。
說到Python,一般都會感覺它關聯著ML,如果不是做ML開發,就會覺得離自己很遠。而實際上,作為一門語言,Python在應用中跟別的語言沒什麼區別,甚至在某些時間,它的方便會讓人感覺很舒服。
試想一下,有個小需求,需要臨時改一些資料庫的數據。怎麼搞?直接寫資料庫腳本?麻煩。開個IDE寫段程式碼?更麻煩。這時候,有Python就很爽了 — 隨便開個Notepad或VIM,寫段程式碼,就搞定了。
很方便,有沒有?
所以,不管做什麼樣的開發,了解一點Python,還是有點意義的。
今天我們就整理一個知識點:Python操作MongoDB資料庫。
為了防止不提供原網址的轉載,特在這裡加上原文鏈接://www.cnblogs.com/tiger-wang/p/13216977.html
一、運行準備
首先,我們需要有Python3 。現在Python全線從v2轉為v3,如果還停留在v2的年代,不妨升一下級。
Python3的安裝不詳細說,官網在//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 //bootstrap.pypa.io/get-pip.py -o get-pip.py
% python3 get-pip.py
也可以去pip官網自行查找安裝。官網在//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,官網在//www.pyinstaller.org。
它的作用,是把您寫的Python程式,轉成各種作業系統下的可執行文件。
PyInstaller安裝很簡單:
% pip install pyinstaller
使用更簡單:
% pyinstaller your_code.py
經過一翻編譯,會生成幾個目錄。其中,dist
目錄下,就是編譯完成的可執行程式。當然,我們的Python程式會引用或依賴一些庫,而可愛的PyInstaller,也很貼心的把這些庫複製到了這個目錄中。
找到目錄中同名的可執行程式,例如這個例子中,將是your_code
,運行之,搞定。
(全文完)
本文的配套程式碼,在//github.com/humornif/Demo-Code/tree/master/0016
微信公眾號:老王Plus 掃描二維碼,關注個人公眾號,可以第一時間得到最新的個人文章和內容推送 本文版權歸作者所有,轉載請保留此聲明和原文鏈接 |