1. 程式人生 > >自制工具將excel檔案批量匯入到mongodb

自制工具將excel檔案批量匯入到mongodb

使用方法

  1. 下載此工具(度盤 密碼: sbv6),這是一個exe檔案,雙擊可直接執行在這裡插入圖片描述
  2. 將這個工具放到你要處理的表格所在的目錄,比如上圖中有一個年級表的示例檔案在這裡插入圖片描述
  3. 確保已啟動mongodb服務在這裡插入圖片描述
  4. 雙擊指令碼工具,啟動控制檯,會提示你輸入要連線/建立的資料庫名以及表格所在路徑(留空則預設會檢查當前目錄以及當前目錄下的“data”資料夾(如果有的話)),由於我們已經把指令碼和表格放在了同一目錄下,所以這裡直接回車即可在這裡插入圖片描述
  5. 等待程式執行完畢後,按任意鍵退出控制檯在這裡插入圖片描述
  6. 在mongo compass中可以檢視資料庫被更新在這裡插入圖片描述

注意事項

  1. 工具可能會被殺軟誤識別為病毒,如果覺得不安全的話,可以自己下載python原始碼(見本文附錄)並自行打包成可執行工具(方法可參考
    這篇文章
  2. 在啟動檔案前,請確保MongoDB服務已啟動(提示:命令列輸入mongod --dbpath $your_db_path$啟動)
  3. 預設會把檔名作為表名錄入
  4. 暫不支援判斷資料庫或表是否已存在,為了您的安全,請自行確保該資料庫或表沒有被覆蓋的風險
  5. 該指令碼預設會檢查當前所在目錄是否有名為“data”的資料夾,如果有的話,會將裡面的檔案作為所有要入庫的excel;沒有的話會將當前目錄中的所有表格型別的檔案(“.xlsx”以及“.xls”字尾)作為待入庫的表格物件。如有其他需求(例如你的表格檔案位於其他盤下的某個目錄裡),請在指令碼啟動後根據控制檯提示填寫你的自定義目錄的絕對路徑
  6. 暫不支援處理“.csv”字尾的表格檔案
  7. 指令碼處理完成後,會提示你按任意鍵退出指令碼控制檯

附錄:python原始碼

import pymongo
import xlrd
import os
import re


def main(db_name, read_dir='data/'):
    """使用說明

    excel一鍵轉mongo刪減版說明(for redevelopment):
		1. 去除了自定義日誌模組lk_logger
		2. 開發者請安裝pymongo,xlrd模組
    
    功能說明:
        1. 支援批量檔案處理
        2. 指令碼啟動後會彈出控制檯,會詢問你要匯入到哪個資料庫(輸入資料庫名稱即可)
        3. 指令碼會預設查詢目錄下的表格檔案,或者你也可以自定義某個絕對路徑的目錄作為引數傳入

    注意事項:
        1. 在啟動檔案前,請確保MongoDB服務已啟動(提示:命令列輸入"mongod --dbpath $your_db_path$"啟動)
        2. 預設會把檔名作為表名錄入
        3. 暫不支援判斷資料庫或表是否已存在,為了您的安全,請自行確保該資料庫或表沒有被覆蓋的風險
        4. 該指令碼預設會檢查當前所在目錄是否有名為"data"的資料夾,如果有的話,會將裡面的檔案作為所有要入庫的excel;沒有的話會將當前目錄中的所有
        表格型別的檔案(xlsx以及xls字尾)作為待入庫的表格物件.如有其他需求(例如你的表格檔案位於其他盤下的某個目錄裡),請在指令碼啟動後根據控制檯
        提示填寫你的自定義目錄的絕對路徑
        5. 暫不支援處理".csv"字尾的表格檔案
        6. 指令碼處理完成後,會提示你按任意鍵退出指令碼控制檯

    :param db_name: str. 要連線/建立的資料庫名稱
    :param read_dir: str. 要讀取的資料夾路徑,可以傳入相對路徑或絕對路徑,路徑名末尾加不加斜槓都可以
    :return:
    """
# 連線/建立資料庫 client = pymongo.MongoClient(host='localhost', port=27017) # 首先啟動客戶端 db = client[db_name] # 然後連線/建立資料庫 # while True: # 等待使用者輸入命令,預設會使用表格的檔名作為待會兒要建立的表的名稱 # cmd = input('would you want to set filename to be collection name? (y/n)') # if cmd == 'y': # break # elif cmd == 'n': # pass # else: # continue # 這裡指令碼預設會查詢指令碼所在的資料夾有沒有名為"data"的資料夾,如果有的話,則將data裡面的檔案認為是要處理的表格 # 如果找不到"data"資料夾,則指令碼會認為使用者把表格放在了與指令碼同級的資料夾中,則指令碼會在同級蒐集所有的檔案 # (後面會自動排除掉型別非表格的檔案,所以不要擔心指令碼把自己當成一個表格) if os.path.exists(read_dir): if read_dir[-1] != '/': read_dir += '/' # '../my_custom_data_folder' --> '../my_custom_data_folder/' # 這裡做一個小處理,如果傳入的路徑引數末尾不含斜槓,則加上一個斜槓 # 之所以這樣做,是為了在後面開啟workbook路徑的時候不會出錯 else: read_dir = os.path._getfullpathname(os.path.abspath(__file__)) # --> r'E:\workspace\smart_tools\excel_2_mongodb_tool\main_app.py' read_dir = read_dir.replace('\\', '/') # --> 'E:/workspace/smart_tools/excel_2_mongodb_tool/main_app.py' read_dir = re.sub(r'(/)(?!.*\1).+$', '', read_dir) + '/' # --> 'E:/workspace/smart_tools/excel_2_mongodb_tool/' print('current directory = {}'.format(read_dir)) """注意事項: 獲取當前指令碼所在的目錄: # 不要用: read_dir = os.path.dirname(__file__) # 該語句在python中可以實現,但在打包成exe後,使用該語句會返回空值錯誤 # 要用: read_dir = os.path._getfullpathname(os.path.abspath(__file__)) read_dir = re.sub(r'(/)(?!.*\1).+$', '', read_dir) # 先獲取檔案的絕對路徑(含指令碼檔名),再把指令碼名用正則去掉 另外需要注意的是正則的使用: # e.g. read_dir = 'E:/workspace/smart_tools/excel_2_mongodb_tool/main_app.py' # 不要用: read_dir = re.sub(r'/.+$', '', read_dir) # 正則預設會貪婪匹配,該語句會匹配到第一個斜槓,結果會返回"E:" # 要用: read_dir = re.sub(r'(/)(?!.*\1).+$', '', read_dir) # 該語句會匹配斜槓最後一次出現的位置,從而正確地去除指令碼名,結果會返回"E:/workspace/smart_tools/excel_2_mongodb_tool" 當然如果覺得正則麻煩的話,也可以用: # e.g. read_dir = 'E:/workspace/smart_tools/excel_2_mongodb_tool/main_app.py' read_dir = '/'.join(read_dir.split('/')[:-1]) + '/' # --> 'E:/workspace/smart_tools/excel_2_mongodb_tool/' """ files = os.listdir(read_dir) # --> ['a.xlsx', 'b.xls', 'c.xlsx', ...] if not files: pring('[W] no excel found in your directory!') raise AttributeError for file in files: if '.' in file and 'xls' in file[-4:]: # 目前僅支援xlsx和xls型別的檔案的識別 print('------------------------------------------------ file = {}'.format(file)) # 列印一條分割線 table_name = file.split('.')[0] # 'a.xlsx' --> ['a', 'xlsx'] --> 'a' current_table = db[table_name] # 以檔名為表名,建立一張表 workbook = xlrd.open_workbook(read_dir + file) # --> open_workbook('data/a.xlsx') sheet = workbook.sheet_by_index(0) # 獲得sheet1的資料 rows_tag = sheet.row_values(0) # 獲得第一行的表格資料,一般來說這就是標題頭,可以作為字典的鍵名使用 print('rows_tag = {}'.format(rows_tag)) for j in range(1, sheet.nrows): # 開始遍歷表格的每一行,將每一行的資料作為一個物件錄入到這張表中 row_data = dict(zip(rows_tag, sheet.row_values(j))) """example 舉個例子說明一下zip(list, list)的作用: a = zip(['iii', 'jjj', 'kkk'], ['uuu', 'vvv', 'www', 'xxx', 'yyy', 'zzz']) print(a) # --> <zip object at 0x0000019F876A8C48> print(dict(a)) # --> {'iii': 'uuu', 'jjj': 'vvv', 'kkk': 'www'} print(list(a)) # --> [('iii', 'uuu'), ('jjj', 'vvv'), ('kkk', 'www')] 所以經過此步驟我們得到的row_data為一個字典物件: { 'name' : 'Mark', 'gender': 'male', 'age' : '23', ... } pymongo可以接受dict型別的資料,所以接下來直接將row_data插入到表中即可 """ current_table.insert_one(row_data) input('script executed over, press anykey to leave... ') if __name__ == '__main__': my_db = input('please input the db name which would be created or connected to: ') my_data_path = input("please input the data path (press enter to use default path: 'data/'): ") if my_data_path: main(my_db, my_data_path) else: main(my_db)