1. 程式人生 > >Python 操作 MongoDB 資料庫

Python 操作 MongoDB 資料庫

寫在之前

MongoDB 也是當下比較火的資料庫之一,因為時代的發展需要 NoSQL,還是老辦法,在本篇文章中呢,我先來介紹一下 MongoDB 資料庫的安裝執行和使用,以及用 Python 連線 MongoDB,下面就開始今天的學習。

MongoDB 簡介

在這之前,我們先來了解一下什麼是 NoSQL:

NoSQL 也就是 Not only SQL,指的是非關係型資料庫,它是為了大規模 Web
應用而生的,它的特徵諸如模式自由、支援簡易複製、簡單的 API、大容量資料等。

MongoDB 是 NoSQL 中的一種,選擇它的原因是它具有如下特點:

  • 面向文件儲存。

  • 對任何物件可索引。

  • 複製和高可用性。

  • 自動分片。

  • 豐富的查詢。

  • 快速就地更新。

基於 MongoDB 的特點,它擅長的領域如下:

  • 大資料。

  • 內容管理和交付。

  • 移動和社交基礎設施。

  • 資料平臺。

如果大家感興趣的話,也可以去學習其它的 NoSQL 資料庫。

安裝 MongoDB

這個和 MySQL 一樣,你要使用它,首先就要安裝。因為篇幅有限且每個人的作業系統都不一樣,具體怎麼安裝,我不在這贅述,網上的教程很多,隨便 Google 一下就是一大堆。

啟動 MongoDB

安裝完畢後就可以啟動資料庫。我在這裡建立一個簡單的庫,並且捎帶說明 MongoDB 的基本要點,目的在於為後面用 Python 來操作它做鋪墊。在這我以 windows 為例,首先進入到 MongoDB 的互動模式下:

在這裡插入圖片描述

上圖我截取了一部分,在 windows 的 cmd 中,進入到你安裝 MongoDB 的目錄下的 bin 資料夾中,執行 mongo.exe 進入到 MongoDB 互動模式。進入之後有點類似 MySQL 的狀態。

在 MongoDB 中,有一個全域性變數 db,使用哪個資料庫,哪個資料庫就會作為物件被賦值給這個全域性變數 db。如果這個資料庫不存在,就會被新建。

> use mydb
switched to db mydb
> db
mydb
>

除非是向這個資料庫中增加實質性的內容,否則它是看不到的。

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

向這個資料庫中增加一些東西,MongoDB 的基本單元是「文件」。所謂的「文件」就是類似於 Python 中的字典,以「鍵/值對」的方式儲存資料。

> book = {"title":"zero study python","author":"rocky","like":"python"}
{ "title" : "zero study python", "author" : "rocky", "like" : "python" }
> db.books.insert(book)
WriteResult({ "nInserted" : 1 })
> db.books.find()
{ "_id" : ObjectId("5bab28b6a1888724cb5ba515"), "title" : "zero study python", "
author" : "rocky", "like" : "python" }

db 指向了資料庫 mydb,books 是這個資料庫裡面的一個集合(類似於 MySQL 中的表),向集合 books 裡面插入了一個文件(文件對應 MySQL 裡面的記錄)。「資料庫」、「集合」、「文件」構成了 MongoDB 資料庫。

上面的操作有一個比較有意思的地方,並沒有 create 之類的命令,用到資料庫,就通過 use ,如果不存在就建立;用到集合,就通過 db. 來使用,如果沒有就建立。可以總結為“隨用,隨取,隨建立”,簡單的一批。

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
mydb    0.000GB

當有了內容以後,就可以看到剛才用到的資料庫 mydb 了。簡單的使用就是這些,下面就來重頭戲啦,畢竟我們是主學 Python 的啊。

安裝 pymongo

要用 Python 來驅動 MongoDB,必須要安裝驅動模組,即 pymongo,這個跟操作 MySQL 是類似的。安裝方法推薦如下(windows 下):

pip3 install pymongo

如果順利就會看到最後的提示:

Installing collected packages: pymongo
Successfully installed pymongo-3.7.1

然後我們來看一下安裝的版本號:

>>> import pymongo
>>> pymongo.version
'3.7.1'

上面 import pymongo 沒有問題,證明一切都可以了。

Python 連線 MongoDB

既然 Python 驅動 MongoDB 的模組 pymongo 已安裝完畢,那麼接下來就是連線,即「建立連線物件」。

>>> import pymongo
>>> pymongo.Connection('localhost',27017)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'Connection'

竟然報錯??怎麼回事??明明很多書上都是這麼寫的,為啥會報錯呢?一定要注意這裡的坑!這個很版本有關係,我剛學的時候這裡直接把我坑傻了。如何你用的是舊版本的 pymongo,比如 2.8 的,你仍然可以用上面的方法,但是你如果用的是新版本的,就得注意一下了,有時候不能盲目的相信書上的東西,因為會有些東西是會變的!

>>> dir(pymongo)

是時候請出我們的 dir 來了,看看哪些方法可用,因為結果太多我就不貼上來了,你可以自行在互動模式執行,執行的結果你會發現裡面沒有 Connection() 這個方法,但是發現有一個 MongoClient(),這是柳暗花明又一村。

>>> client = pymongo.MongoClient('localhost',27017)

隨著上面這行程式碼的執行,Python 已經和 MongoDB 建立了連線。剛才我們已經建立了一個數據庫 mydb,並且在這個庫裡面有一個集合 books,於是:

>>> mdb = client.mydb

或者是:

>>> mdb = client['mydb']

上面的程式碼獲得了資料庫 mydb,並賦值給變數 mdb。

>>> mdb.collection_names()
[u'books']

檢視集合,發現了我們已經建立好的那個 books,於是再獲取這個集合,並賦值給一個變數 books:

>>> books = mdb["books"]

或者是:

>>> books = mdb.books

接下來,我們就可以操作這個集合中的具體內容啦。

上面的 books 所引用的是一個 MongoDB 的集合物件,它跟前面學習過的其它物件一樣,也有一些方法供我們使用。

編輯

>>> type(books)
<class 'pymongo.collection.Collection'>
>>> dir(books)

還是用我們的老朋友 dir() ,你在自己的互動模式下執行的結果會發現有很多的方法,這麼多方法在這裡我不會一一介紹,只是按照「增刪改查」的常用功能介紹幾種,大家可以用 help() 去檢視每一種方法的使用說明。

>>> books.find_one()
{u'like': u'python', u'_id': ObjectId('5bab28b6a1888724cb5ba515'), u'author': u'
rocky', u'title': u'zero study python'}

這裡提醒大家注意的是,MongoDB 的 shell 中的命令與 pymongo 中的方法有時候會稍有差別,這個務必小心。

目前在集合 books 中只有一個文件,如果還想再增加,就需要進行「增刪改查」的常規操作。

1.增加

>>> b2 = {"title":"physics","author":"leey","like":"English"}
>>> books.insert(b2)
ObjectId('5badb7c8b2e7d42bccfb6b30')

上面成功的向集合中增加一個文件。

>>> books.find().count()
2

這是檢視當前集合有多少個文件的方式,返回值為 2,則說明集合中有兩個文件,但還是要看看內容的:

>>> books.find_one()
{u'like': u'python', u'_id': ObjectId('5bab28b6a1888724cb5ba515'), u'author': u'
rocky', u'title': u'zero study python'}

這個命令就不行,因為它只返回第一條,必須要:

>>> for i in books.find():
...    print(i)
...
{u'like': u'python', u'_id': ObjectId('5bab28b6a1888724cb5ba515'), u'author': u'
rocky', u'title': u'zero study python'}
{u'title': u'physics', u'_id': ObjectId('5badb7c8b2e7d42bccfb6b30'), u'like': u'
English', u'author': u'leey'}

在 books 引用的印象中有 find() 方法,它返回的是一個可迭代物件,包含著集合中所有的文件。

由於文件是「鍵/值對」,不一定每一個文件的結構都要一樣。比如可以在集合中插入像下面這樣的文件:

>>> books.insert({"name":"qwer"})
ObjectId('5badb9f1b2e7d42bccfb6b31')
>>> for i in books.find():
...    print(i)
...
{u'like': u'python', u'_id': ObjectId('5bab28b6a1888724cb5ba515'), u'author': u'
rocky', u'title': u'zero study python'}
{u'title': u'physics', u'_id': ObjectId('5badb7c8b2e7d42bccfb6b30'), u'like': u'
English', u'author': u'leey'}
{u'_id': ObjectId('5badb9f1b2e7d42bccfb6b31'), u'name': u'qwer'}

如果有多個文件,想同時插入到集合中,可以像下面這樣做:

>>> n1 = {"title":"enter","name":"bash"}
>>> n2 = {"title":"code","name":"john"}
>>> n3 = {"title":"warner","name":"lisp"}
>>> n = [n1,n2,n3]
>>> n
[{'name': 'bash', 'title': 'enter'}, {'name': 'john', 'title': 'code'}, {'name':
'lisp', 'title': 'warner'}]


>>> books.insert(n)
[ObjectId('5badc702b2e7d42bccfb6b32'), ObjectId('5badc702b2e7d42bccfb6b33'), Obj
ectId('5badc702b2e7d42bccfb6b34')]

這樣就完成了所謂的批量插入,檢視一下文件個數:

>>> books.find().count()
6

這裡需要提醒一下的是,批量插入的文件大小是有限制的,具體是多少沒有碰到過,一般情況下或許達不到上限,如果遇到極端情況,那麼就要多多注意啦。

2.查詢

如果要查詢的話,除了通過迴圈以外,能不能按照某個條件查詢呢?比如查詢 name = bash 的文件:

>>> books.find_one({"name":"bash"})
{u'_id': ObjectId('5badc702b2e7d42bccfb6b32'), u'name': u'bash', u'title': u'ent
er'}

對於查詢結果,還可以進行排序:

>>> for i in books.find().sort("title",pymongo.ASCENDING):
...    print(i)
...
{u'_id': ObjectId('5badb9f1b2e7d42bccfb6b31'), u'name': u'qwer'}
{u'_id': ObjectId('5badc702b2e7d42bccfb6b33'), u'name': u'john', u'title': u'cod
e'}
{u'_id': ObjectId('5badc702b2e7d42bccfb6b32'), u'name': u'bash', u'title': u'ent
er'}
{u'title': u'physics', u'_id': ObjectId('5badb7c8b2e7d42bccfb6b30'), u'like': u'
English', u'author': u'leey'}
{u'_id': ObjectId('5badc702b2e7d42bccfb6b34'), u'name': u'lisp', u'title': u'war
ner'}
{u'like': u'python', u'_id': ObjectId('5bab28b6a1888724cb5ba515'), u'author': u'
rocky', u'title': u'zero study python'}

這裡按照 title 的升序排列的,注意 sort() 的第二個引數,意思是升序排列,如果按照降序的話,就需要將引數修改為 pymongo.DESCEDING。

如果你看到這裡,請務必注意 MongoDB 中的每個文件,本質上都是 鍵/值 對的類字典結構,這種結構一經 Python 讀出來,就可以用字典中的各種方法來操作。

你是否還能記起我們之前講過的 Json,這個也是類字典格式。但是用 Python 從 MongoDB 中讀到的類字典資料,卻無法直接用 json.dumps() 方法操作。

3.更新

對於已有的資料庫來說,更新資料是常用的操作。比如更新 name 為 lisp 的文件:

>>> books.update({"name":"lisp"},{"$set":{"title":"new physics","author":"lisp"}
})
{'updatedExisting': True, u'nModified': 1, u'ok': 1.0, u'n': 1}

在更新的時候,用了一個 $set 修改器,它可以用來指定鍵值,如果鍵不存在則建立。關於更多的修改器,如下所示(截圖來源於網上):

在這裡插入圖片描述

4.刪除

刪除可以用 remove() 方法:

>>> books.remove({"name":"bash"})
{u'ok': 1.0, u'n': 1}
>>> books.find_one({"name":"bash"})
>>>

這個是將整個文件全部刪除。當然了,也可以根據 MongoDB 的語法規則寫個條件,按照條件刪除。

5.索引

索引的目的是為了讓查詢的速度更快,但是在實際應用中,是否建立索引要視情況而定,因為建立索引是有代價的。

>>> books.create_index([("title",pymongo.DESCENDING),])
u'title_-1'

寫在之後

Python 操作 MongoDB 資料庫的這篇文章僅僅是對 pymongo 模組做了一個非常簡單的介紹,在實際的使用過程中,上面的知識其實是很有限的,所以還是需要大家根據具體應用場景再結合 MongoDB 的相關知識去嘗試新的語句。

更多內容,歡迎關注公眾號「Python空間」,期待和你的交流。
在這裡插入圖片描述