用MongoDB開發員工資訊管理系統
- 2020 年 4 月 10 日
- 筆記
本項目的最終結果會以網頁形式呈現,讀者只需要完成整個系統中關於MongoDB 操作這部分程式碼的開發即可。
完成以後,將會得到一個人員資訊管理網頁,如圖所示。在頁面的末尾可以看到用於新增數據的「添加人員」按鈕。通過這個網頁,可以查看當前的所有人員資訊,可以增加、修改、刪除人員資訊。

image.png
1.添加資訊
(1)可以單擊「添加人員」按鈕,打開「添加資訊」對話框。
(2)在「添加資訊」對話框中輸入相應的資訊,則資訊會被添加到MongoDB 中,同時也出現在網頁中,如圖所示:

image.png

image.png
2.編輯資訊
(1)單擊介面每條資訊後面的「編輯」按鈕,會打開「編輯資訊」對話框。「編輯資訊」對話框中已經自動填入了當前人員的資訊,除「工號」與「年齡」外,其他資訊都可以修改。其中,年齡會通過修改「出生年月日」而自動修改。

image.png
2)修改一項或多項以後,單擊「更新」按鈕更新本條數據。
3.刪除資訊
單擊每一條資訊後面的「刪除」按鈕,則可以將當前資訊刪除,如圖所示。

image.png
工號一旦被自動生成就固定不變,不會因為刪除某個人的資訊而導致後面人的工號發生改變。
2 準備工作
2.1 拉取項目
git clone https://github.com/sunsharing-note/MonogoDB.git
2.1 了解文件結構
項目的初始文件結構如下:

image.png
其中主要文件說明如下:
● Pipfile與Pipfile.lock:Pipenv配置運行環境的文件,用來記錄項目所需要的第三方庫
● answer文件夾下面的DataBaseManager.py:本項目的參考答案。讀者在自己完成項目以後可以將自己的程式碼與參考程式碼進行對比
● bin文件夾下的generate_data.py:用來向資料庫中插入初始數據
● main.py、static、templates、util 文件夾:其中是本項目網站的後台和前台相關的程式碼,讀者不需要關心
2.2 搭建項目運行環境
在Python開發中,常使用pip來安裝不同的第三方庫。如果把所有第三方庫全部安裝到系統的Python環境中,則可能會導致系統環境不穩定。而且,如果兩個不同的項目依賴於同一個第三方庫的不同版本,那麼處理衝突也非常麻煩。
virtualenv 是一個創建 Python 虛擬環境的工具,它可以為每一個Python 項目創建不同的Python虛擬環境,各個環境之間互相隔離,從根本上解決了第三方庫衝突的問題。
由於virtualenv命令的參數眾多而且操作複雜,不利於初學者直接使用,因此需要使用一個更加簡單的工具來管理virtualenv,本文使用Pipenv來實現這一目的。
Pipenv會自動調用virtualenv創建虛擬環境,並在虛擬環境中安裝第三方庫,所以使用Pipenv會大大簡化Python項目的環境搭建工作。
1.安裝Pipenv
安裝Pipenv需要在Linux/macOS的終端或者Windows的DOS窗口中執行pip命令:
python3 -m pip install pipenv
2.創建本項目所需要的Python環境
(1)安裝完成後,通過命令行或者終端進入本項目所在的文件夾(例如:E:文檔資料SourceCodeofMongoRedis-masterproject_1)。
(2)進入後,執行如下命令就能創建本項目所需要的Python環境:pipenv install
(3)運行命令以後,Pipenv會自動讀取Pipfile和Pipfile.lock這兩個文件,從而知道需要安裝哪些第三方庫的什麼版本。運行效果如圖所示:

image.png
3.進入虛擬環境
(1)安裝完成以後,根據提示執行以下命令:
pipenv shell
(2)自動進入專門為本項目訂製的虛擬環境,如圖所示,方框框住的部分是本項目虛擬環境的名字,提示當前終端處於虛擬環境中。

image.png
提示:虛擬環境提示有多種顯示形式,這取決於終端的顯示設置。所以,可能大家看到的與圖中所示的位置或者格式略有差異。
此時,如果使用的是「python3×××.py」命令,則調用的是虛擬環境中的Python 3,不會受系統環境的影響。在本項目的開發過程中,請全程不要關閉當前這個終端窗口,因為本項目是前台運行,涉及的所有命令都需要在這個窗口中執行。
提示:如果不小心關閉了這個終端窗口,則需要執行命令重啟虛擬環境。 如在macOS/Linux中,則需要執行以下兩條命令進入項目文件夾並啟動虛擬環境: cd ~/mongoredis/project_1 pipenv shell 如在Windows中,則需要執行以下兩條命令進入項目文件夾並啟動虛擬環境: cd C:project_1 pipenv shell 關於Pipenv的詳細使用說明,讀者可以參考https://github.com/pypa/pipenv。
2.3 啟動項目
設置好虛擬環境後,就可以啟動網站了
1.Linux/macOS系統對於Linux/macOS系統,在虛擬環境中執行以下命令:
export FLASK_APP=main.py flask run
其中,第1行程式碼添加環境變數,變數名為「FLASK_APP」,值為「main.py」;第2行程式碼通過flask啟動網站。
2.Windows系統
對於Windows系統,按以下步驟來啟動項目。(本文以windows系統操作為例)
(1)在DOS窗口中以下執行命令:
set FLASK_APP=main.py flask run
(2)運行效果如圖所示:

image.png
(3)打開瀏覽器,輸入網址:http://127.0.0.1:5000,可以看到如圖所示的頁面:

image.png
此時,即使沒有啟動MongoDB,也可以看到頁面上有三條測試數據,沒法進行操作,僅作測試展示
● 單擊「添加人員」按鈕,會彈出「添加資訊」對話框,但是添加的任何資訊都不會出現在頁面上,也不會被寫入資料庫中。
● 單擊「編輯」按鈕也能打開編輯資訊對話框,但是對資訊的任何修改都不會生效。
● 單擊「刪除」按鈕無法刪除當前的三條測試數據。
打開your_code_here文件夾下面的DataBaseManager.py文件,其中的程式碼如圖所示:

image.png
本項目實現 DataBaseManager 類下面的不同方法,從而使人員管理系統可以正常工作。本項目中所有需要讀者修改的地方都在程式碼的注釋中進行了提示。
3 項目開發過程
3.1 生成初始數據
在項目的bin文件夾下有一個generate_data.py文件,文件中的程式碼如圖所示:

image.png
在本地啟動 MongoDB,運行這個文件中的程式碼,則會在本地 MongoDB中創建一個名為「chapter_4」的資料庫,並在其中創建一個名為「people_info」的集合。初始狀態會向集合中插入19條數據,如圖所示:

image.png
提示:「初始數據生成程式生成」的人名、年齡和地址都是隨機拼接的,因此每一位讀者生成的初始數據都是不一樣的。但可以確定的是,人名「小四」和「小六」中間沒有「小五」
3.1 實現「查詢數據」功能
查詢數據對應了DataBaseManager類裡面的query_info()方法。在初始狀態下,這個方法返回的是三條假數據

image.png
方框框住的程式碼為:
def query_info(self): """ 你需要在這裡實現這個方法, 查詢集合people_info並返回所有"deleted"欄位為0的數據。 注意返回的資訊需要去掉_id """ return [ {'id': 1, 'name': '測試數據', 'age': 18, 'birthday': '2000-01-02', 'origin_home': '測試數據', 'current_home': '測試數據'}, {'id': 2, 'name': '測試數據', 'age': 18, 'birthday': '2000-01-02', 'origin_home': '測試數據', 'current_home': '測試數據'}, {'id': 3, 'name': '測試數據', 'age': 18, 'birthday': '2000-01-02', 'origin_home': '測試數據', 'current_home': '測試數據'}] 現在的目標是,用 query_info()方法查詢 MongoDB,並以列表的形式返回集合裡面的所有數據。由於無論是查詢、增加、修改,還是刪除數據,都會涉及資料庫連接,因此,可以先在__init__()方法中創建資料庫連接對象,這樣在後面的其他方法中都能夠直接使用,不需要多次初始化資料庫連接
1.創建資料庫連接對象
修改__init__()方法中的程式碼,連接資料庫並定位到people_info集合,構造函數
def __init__(self): """ 你需要在這裡初始化MongoDB的連接,連上本地MongoDB,庫名為chapter_4,集合名為people_info """ client = MongoClient() database = client.chapter_4 self.handler = database.people_info
其中,主要程式碼說明如下:
● 第5行程式碼:創建MongoDB的連接
● 第6行程式碼:指定使用「chapter_4」資料庫
● 第7行程式碼:指定使用「people_info」集合
2. 查詢集合中所有「deleted」欄位為0的資訊
接下來完成query_info()方法,查詢集合中所有「deleted」欄位為0的資訊
def query_info(self): """ 你需要在這裡實現這個方法, 查詢集合people_info並返回所有"deleted"欄位為0的數據 注意返回的資訊需要去掉_id """ info_list = list(self.handler.find({'deleted': 0}, {'_id': 0})) return info_list 其中,主要程式碼說明如下:
● 第8行程式碼:「self.handler.find({'deleted': 0},{'_id': 0})」查詢到所有deleted欄位為0的數據,去掉ObjectId以後返回。再使用Python的list()方法把pymongo返回的對象轉換為包含字典的列表。
● 第9行程式碼:將轉換成的包含字典的列表返回。
在虛擬環境中,使用「Ctrl+C」組合鍵關閉網站程式,然後再重新啟動。
刷新瀏覽器後可以看到,資料庫中的資訊已經成功顯示在網頁中了。

img
3.2 實現「添加數據」功能
添加數據的邏輯如下:
- (1)如果people_info集合中沒有數據,那麼添加的人員工號為「1」
- (2)如果people_info中有數據,那麼新的人員工號是「已有最大工號加1」
- (3)插入數據
1. 查詢已有工號
首先需要查詢people_info集合,尋找當前最大的工號。根據前面介紹的添加邏輯中的(1)和(2)兩點,完善_query_last_id()方法
def _query_last_id(self): """ 你需要實現這個方法,查詢當前已有數據裡面最新的id是多少 返回一個數字,如果集合裡面至少有一條數據,那麼就返回最新數據的id, 如果集合裡面沒有數據,那麼就返回0 提示:id不重複,每次加1 :return: 最新ID """ last_info = self.handler.find({}, {'_id': 0, 'id': 1}).sort('id', -1).limit(1) return last_info[0]['id'] if last_info else 0 其中,主要程式碼說明如下。
● 第10行程式碼:首先查詢people_info集合,以「id」欄位倒序排列,只取倒序排列以後的第1條數據,即id最大的那一條數據。
● 第11行程式碼:如果people_info不為空,那麼if last_info判斷語句會執行if左邊的語句,並且變數last_info可以像列表一樣讀取下標為0的元素,再讀取這個元素的id,這就是當前最大的id了,讀取以後返回。如果people_info集合是空的,那麼if last_info判斷語句會執行else右邊的語句,返回整數0。
2 添加新數據
add_info()方法首先調用_query_last_id()方法獲得當前最大的id,然後把這個id加1作為新的id。再將新的id放到參數需要插入的字典「para_dict」中並插入資料庫中。
3 測試添加數據
添加好數據之後,會自動添加到最後,如圖所示:

image.png
3.3 實現「更新數據」功能
1.實現數據更新邏輯
更新數據的邏輯非常簡單,根據工號id找到MongoDB中對應的記錄並更新即可。涉及的程式碼如下:
def update_info(self, people_id, para_dict): """ 你需要實現這個方法。這個方法用來更新人員資訊。 更新資訊是根據people_id來查找的,因此people_id是必需的。 :param people_id: 人員id,數字 :param para_dict: 格式為{'name': 'xxx', 'age': 12, 'birthday': '2000-01-01', 'origin_home': 'xxx', 'current_home': 'yyy'} :return: True或者False """ try: y = self.handler.update_one({'id': people_id}, {'$set': para_dict}) print(y) except Exception as e: print('更新數據錯誤,報錯資訊如下:{}'.format(e)) return False return True 其中,主要程式碼說明如下。
● 第10行程式碼:根據id更新數據。para_dict的格式與添加新數據時的相同。
● 第11行程式碼:列印更新返回的對象。這是一行不重要的語句,可以省略。
● 第9行與第12行,使用try...except Exception把更新程式碼「包」起來,這樣遇到更新數據出錯時就會把錯誤資訊列印出來,並返回False。
3.4 實現「刪除數據」功能
1.實現刪除數據的邏輯
為了防止數據的誤刪除,使用「假刪除」是一個簡單有效的方法。在查詢數據時,用到的查詢條件為「deleted欄位為0」,那麼只要把deleted欄位改為非0就可以讓數據查不出來,也就變相實現了刪除的功能。因此,刪除數據的本質仍然是更新數據
def del_info(self, people_id): """ 你需要實現這個方法。請注意,此處需要使用"假刪除", 把刪除操作寫為更新"deleted"欄位的值為1 :param people_id: 人員id :return: True或者False """ return self.update_info(people_id, {'deleted': 1}) 其中,第8行程式碼調用了update_info()這個方法,傳入了將要被刪除的工號id。與前面更新用戶資訊不同,刪除資訊時只需要更新「deleted」欄位,把該欄位的值設為1。這樣在數據查詢階段就無法查出數據了
2. 刪除數據測試
l例如刪除工號為「13」人員的資訊,在網頁上點擊這一行數據後面的刪除按鈕,則在網頁上已經不能看到工號為「12」的這個人員的資訊了。在資料庫中,這個人員的deleted欄位變成了1

image.png

image.png
提示:目前互聯網上很多聲稱能夠註銷並刪除帳號的網站,幾乎都是使用的假刪除。雖然用戶「註銷」以後確實無法登錄,但網站並不會刪除用戶的資訊,只是通過修改資料庫中的某個欄位,讓這個帳號看起來像是被刪除了而已。
小結
使用一個人員管理網站的實例來幫助讀者鞏固 MongoDB 的基本操作。整個過程使用基於 Python 的網路框架 Flask 來實現。讀者只需要修改 your_code_here 文件夾下面的DataBaseManager.py中的相應方法,就可以用圖形化的方式直觀地看到程式碼的運行結果,希望大家能夠通過本項目的學習,能夠明白如何使用python來進行MongoDB的學習,在日常工作中可以使用python來進行數據的入庫等操作,方便數據的分析和管理。