真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何用Python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫

這篇文章給大家介紹如何用Python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

創(chuàng)新互聯(lián)主要從事網(wǎng)站制作、網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)尼元陽,十年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792

我是一名掙扎在編程鏈底端的pythoner,工作中既要和數(shù)據(jù)打交道,也要保持和erp系統(tǒng),web網(wǎng)站友好的"溝通"···,我會時不時的分享下工作中遇到那點事,包括個人覺得值得記錄的編程小技巧,還有就是遇到的問題以及解決方案,還有源碼的閱讀等等,可能也有編程中的生活感悟,不說了,我要去重構(gòu)我的程序了

基于python, 使用pandas,  pyMySQL等三方庫實現(xiàn)了向數(shù)據(jù)庫中高效批量插入數(shù)據(jù),一方面提供被網(wǎng)上很多瞎轉(zhuǎn)載的答案給坑蒙了的人(因為我也是),一方面自己也做個筆記,以后方便查閱

需求原因

最近在處理一個需求,有關(guān)批量往數(shù)據(jù)庫插入數(shù)據(jù)的,描述如下

  • 原來的程序是基于sql的存儲過程進(jìn)行數(shù)據(jù)的更新修改操作,由于數(shù)據(jù)量較大,導(dǎo)致對數(shù)據(jù)庫壓力太大,于是需要將程序重構(gòu)為用python讀取文件的方式將數(shù)據(jù)做計算處理,減少這部分的壓力,最后僅僅將計算的結(jié)果調(diào)用aws的lambda服務(wù)重新更新到數(shù)據(jù)庫中就可以了,減少了極大的壓力,也降低了成本。涉及數(shù)據(jù)庫主要是插入及更新操作

版本庫信息

  • 基于linux系統(tǒng)寫的

  • 三方庫 >>> pandas 1.0.5, pymysql 0.9.3

  • python版本 >>> 3.7

  • 標(biāo)準(zhǔn)庫 >> os

邏輯梳理

實際上,最后一步,要寫入數(shù)據(jù)庫的文件數(shù)據(jù)是存儲在內(nèi)存中的。因為讀取文件后進(jìn)行的計算都是在內(nèi)存中進(jìn)行的,那么計算的結(jié)果也沒必要再寫到本地,再去讀取,再寫入數(shù)據(jù)庫,這是會影響程序的效率的。邏輯如下

  • 讀取文件

  • 文件的拼接及計算,生成新的df

  • 初始化數(shù)據(jù)庫的連接

  • 將df所需數(shù)據(jù)轉(zhuǎn)換為元組數(shù)據(jù)(取決于數(shù)據(jù)庫的三方庫的接口是如何支持批量操作的)

  • 將數(shù)據(jù)寫入數(shù)據(jù)庫

  • 檢查數(shù)據(jù)庫內(nèi)容即可

分步實現(xiàn)及分析

讀取文件

給文件路徑,然后去讀文件就行了,強(qiáng)調(diào)一下需要注意的點

  • 絕對路徑: 這種最簡單,直接給路徑字符串就行了,但是一旦文件夾目錄結(jié)構(gòu)變化,就需要頻繁的改

  • 相對路徑:  我一般喜歡先在腳本中定位當(dāng)前腳本的位置,然后通過相對路徑去找,這樣只要你整個包內(nèi)部的目錄結(jié)構(gòu)不變化,都不用改,就算部署上線也是直接根據(jù)包的位置來,很方便

  • pandas默認(rèn)會將所有數(shù)字讀取為float類型,所以對于那種看起來是數(shù)字,但實際上是需要當(dāng)作字符串使用的字段進(jìn)行類型的轉(zhuǎn)換

import pandas as pd  import numpy as np  # 當(dāng)前腳本的位置 current_folder_path = os.path.dirname(__file__)  # 你的文件的位置 your_file_path2 = os.path.join(current_folder_path, "文件的名字1") your_file_path3 = os.path.join(current_folder_path, "文件的名字2")  # 我這里是以讀取csv文件為例, delimiter為我們內(nèi)部約定的列之間的分割符 df1 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t") df2 = pd.read_csv(your_file_path3, dtype={"column1": str, "column2": str}, delimiter="/t")

文件的拼接及計算

文件的拼接主要就是merge和concat兩個語法的使用,強(qiáng)調(diào)一下小知識點

  • merge語法主要是對應(yīng)于sql語言的內(nèi)連接,外連接,左連接和右連接等

  • concat主要是用來將相同結(jié)構(gòu)的df單純的拼接起來(也就是列表的總行數(shù)增加)

# 這里以左連接舉例, 假設(shè)只有兩個文件拼接 ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left")

初始化連接

導(dǎo)入三方庫pymysql,初始化連接

# pymysql的接口獲取鏈接 def mysql_conn(host, user, password, db, port=3306, charset="utf8"):   # 傳參版本   conn = pymysql.connect(host=host, user=user, password=password, database=db, port=port, charset=charset)   return conn

對應(yīng)接口轉(zhuǎn)換數(shù)據(jù)

  1. 數(shù)據(jù)插入要考慮寫入一個事務(wù),因為失敗的話,要保證對數(shù)據(jù)庫沒有影響

  2. 構(gòu)造符合對應(yīng)接口的數(shù)據(jù)格式,通過查詢,pymysql有兩種可以執(zhí)行語句的接口

  • execute(單條插入語句)

  • 執(zhí)行單條語句的接口

  1. 類似這種: Insert into table_name (column) values (value);

  2. executemany(批量插入語句)

  • 執(zhí)行多條語句的接口

  • 類似這種: Insert into table_name (column1, column2, column3) values (value1,  value2, value3);

具體實現(xiàn)如下

# 先創(chuàng)建cursor負(fù)責(zé)操作conn接口 conn = mysql_conn("your db host", "your username", "your password", "db name") cursor = conn.cursor() # 開啟事務(wù) conn.begin()  #############      構(gòu)造批量數(shù)據(jù)的過程            #############  # 先構(gòu)造需要的或是和數(shù)據(jù)庫相匹配的列 columns = list(df.columns) # 可以刪除不要的列或者數(shù)據(jù)庫沒有的列名 columns.remove("列名") # 重新構(gòu)造df,用上面的columns,到這里你要保證你所有列都要準(zhǔn)備往數(shù)據(jù)庫寫入了 new_df = df[columns].copy()  # 構(gòu)造符合sql語句的列,因為sql語句是帶有逗號分隔的,(這個對應(yīng)上面的sql語句的(column1, column2, column3)) columns = ','.join(list(new_df.columns))  # 構(gòu)造每個列對應(yīng)的數(shù)據(jù),對應(yīng)于上面的((value1, value2, value3)) data_list = [tuple(i) for i in gdsord_df.values] # 每個元組都是一條數(shù)據(jù),根據(jù)df行數(shù)生成多少元組數(shù)據(jù)  # 計算一行有多少value值需要用字符串占位 s_count = len(data_list[0]) * "%s,"  # 構(gòu)造sql語句 insert_sql = "insert into " + "數(shù)據(jù)庫表名" + " (" + columns + ") values (" + s_count[:-1] + ")"

將數(shù)據(jù)寫入數(shù)據(jù)庫

這個簡單,直接上代碼

cursor.executemany(insert_sql, data_list) conn.commit() cursor.close() conn.close()

檢查數(shù)據(jù)庫是否插入成功

如果沒問題的話,就可以同時進(jìn)行多個文件讀寫,計算,最后啟用多線程同時向數(shù)據(jù)庫中寫入數(shù)據(jù)了,非常高效!

完整代碼

import pandas as pd  import numpy as np   # pymysql接口 def mysql_conn(host, user, password, db, port=3306, charset="utf8"):   conn = pymysql.connect(host=host, user=user, password=password, database=db, port=port, charset=charset)   return conn   # 當(dāng)前腳本的位置 current_folder_path = os.path.dirname(__file__)  # 你的文件的位置 your_file_path2 = os.path.join(current_folder_path, "文件的名字1") your_file_path3 = os.path.join(current_folder_path, "文件的名字2")  # 我這里是以讀取csv文件為例, delimiter為我們內(nèi)部約定的列之間的分割符 df1 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t") df2 = pd.read_csv(your_file_path3, dtype={"column1": str, "column2": str}, delimiter="/t") # 合并 ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left")  # 先創(chuàng)建cursor負(fù)責(zé)操作conn接口 conn = mysql_conn("your db host", "your username", "your password", "db name") cursor = conn.cursor() # 開啟事務(wù) conn.begin()  # 先構(gòu)造需要的或是和數(shù)據(jù)庫相匹配的列 columns = list(df.columns) # 可以刪除不要的列或者數(shù)據(jù)庫沒有的列名 columns.remove("列名") # 重新構(gòu)造df,用上面的columns,到這里你要保證你所有列都要準(zhǔn)備往數(shù)據(jù)庫寫入了 new_df = df[columns].copy()  # 構(gòu)造符合sql語句的列,因為sql語句是帶有逗號分隔的,(這個對應(yīng)上面的sql語句的(column1, column2, column3)) columns = ','.join(list(new_df.columns))  # 構(gòu)造每個列對應(yīng)的數(shù)據(jù),對應(yīng)于上面的((value1, value2, value3)) data_list = [tuple(i) for i in gdsord_df.values] # 每個元組都是一條數(shù)據(jù),根據(jù)df行數(shù)生成多少元組數(shù)據(jù)  # 計算一行有多少value值需要用字符串占位 s_count = len(data_list[0]) * "%s,"  # 構(gòu)造sql語句 insert_sql = "insert into " + "數(shù)據(jù)庫表名" + " (" + columns + ") values (" + s_count[:-1] + ")" try:   cursor.executemany(insert_sql, data_list)   conn.commit()   cursor.close()   conn.close() except Exception as e:   # 萬一失敗了,要進(jìn)行回滾操作   conn.rollback()   cursor.close()   conn.close()

關(guān)于如何用Python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


分享標(biāo)題:如何用Python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫
本文地址:http://weahome.cn/article/pcpppj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部