一文說通MongoDB via Python操作

Tiger.Wang發表於2020-07-01

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_oneinsert_many,對應建立一條資料和多條資料。

result = collection.insert_one(article1)
result = collection.insert_many([article1, article2])

這兩個方法返回值與insert返回值略有不同,返回的是個物件。

insert_one返回InsertOneResultInsertOneResult.inserted_id才是_id值。

insert_many返回InsertManyResultInsertManyResult.inserted_ids_id的列表。

6. 查詢資料

查詢資料有兩個方法:find_onefind

先說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_oneupdate_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_onedelete_many。用法和更新相似:

filter = {"article_id"1}
result = collection.delete_one(filter)
print(type(result))

同樣的,delete_one也只會刪除匹配到的資料集中第一條資料。

11. 原子級處理

這是MongoDB中的一個特色操作,也是早期MongoDB的無奈之選。因為早期版本的MongoDB並不支援事務處理。而上面講到的更新和刪除,並不能保證併發情況下的資料安全。

MongoDB為了解決這個併發的資料問題,增加了三個原子級的處理,對應於PyMongo的三個方法:find_one_and_updatefind_one_and_replacefind_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

掃描二維碼,關注個人公眾號,可以第一時間得到最新的個人文章和內容推送

本文版權歸作者所有,轉載請保留此宣告和原文連結

相關文章