偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

100%讓你在10分鐘內(nèi)學(xué)會(huì)如何用Python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫(kù)

開發(fā) 后端 大數(shù)據(jù)
本文基于python, 使用pandas, pymysql等三方庫(kù)實(shí)現(xiàn)了向數(shù)據(jù)庫(kù)中高效批量插入數(shù)據(jù),一方面提供被網(wǎng)上很多瞎轉(zhuǎn)載的答案給坑蒙了的人(因?yàn)槲乙彩?,一方面自己也做個(gè)筆記,以后方便查閱

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

 

100%讓你在10分鐘內(nèi)學(xué)會(huì)如何用python將數(shù)據(jù)批量的插入到數(shù)據(jù)庫(kù)

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

需求原因

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

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

版本庫(kù)信息

  • 基于linux系統(tǒng)寫的
  • 三方庫(kù) >>> pandas 1.0.5, pymysql 0.9.3
  • python版本 >>> 3.7
  • 標(biāo)準(zhǔn)庫(kù) >> os

邏輯梳理

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

  • 讀取文件
  • 文件的拼接及計(jì)算,生成新的df
  • 初始化數(shù)據(jù)庫(kù)的連接
  • 將df所需數(shù)據(jù)轉(zhuǎn)換為元組數(shù)據(jù)(取決于數(shù)據(jù)庫(kù)的三方庫(kù)的接口是如何支持批量操作的)
  • 將數(shù)據(jù)寫入數(shù)據(jù)庫(kù)
  • 檢查數(shù)據(jù)庫(kù)內(nèi)容即可

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

讀取文件

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

  • 絕對(duì)路徑: 這種最簡(jiǎn)單,直接給路徑字符串就行了,但是一旦文件夾目錄結(jié)構(gòu)變化,就需要頻繁的改
  • 相對(duì)路徑: 我一般喜歡先在腳本中定位當(dāng)前腳本的位置,然后通過相對(duì)路徑去找,這樣只要你整個(gè)包內(nèi)部的目錄結(jié)構(gòu)不變化,都不用改,就算部署上線也是直接根據(jù)包的位置來,很方便
  • pandas默認(rèn)會(huì)將所有數(shù)字讀取為float類型,所以對(duì)于那種看起來是數(shù)字,但實(shí)際上是需要當(dāng)作字符串使用的字段進(jìn)行類型的轉(zhuǎn)換
  1. import pandas as pd  
  2. import numpy as np 
  3.  
  4. # 當(dāng)前腳本的位置 
  5. current_folder_path = os.path.dirname(__file__) 
  6.  
  7. # 你的文件的位置 
  8. your_file_path1 = os.path.join(current_folder_path, "文件的名字1"
  9. your_file_path2 = os.path.join(current_folder_path, "文件的名字2"
  10.  
  11. # 我這里是以讀取csv文件為例, delimiter為我們內(nèi)部約定的列之間的分割符 
  12. df1 = pd.read_csv(your_file_path1, dtype={"column1": str, "column2": str}, delimiter="/t"
  13. df2 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t"

文件的拼接及計(jì)算

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

  • merge語(yǔ)法主要是對(duì)應(yīng)于sql語(yǔ)言的內(nèi)連接,外連接,左連接和右連接等
  • concat主要是用來將相同結(jié)構(gòu)的df單純的拼接起來(也就是列表的總行數(shù)增加)
  1. # 這里以左連接舉例, 假設(shè)只有兩個(gè)文件拼接 
  2. ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left"

初始化連接

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

  1. # pymysql的接口獲取鏈接 
  2. def mysql_conn(host, userpassword, db, port=3306, charset="utf8"): 
  3.   # 傳參版本 
  4.   conn = pymysql.connect(host=host, user=userpassword=passworddatabase=db, port=port, charset=charset) 
  5.   return conn 

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

  1. 數(shù)據(jù)插入要考慮寫入一個(gè)事務(wù),因?yàn)槭〉脑挘WC對(duì)數(shù)據(jù)庫(kù)沒有影響
  2. 構(gòu)造符合對(duì)應(yīng)接口的數(shù)據(jù)格式,通過查詢,pymysql有兩種可以執(zhí)行語(yǔ)句的接口
  • execute(單條插入語(yǔ)句)
  • 執(zhí)行單條語(yǔ)句的接口
  1. 類似這種: Insert into table_name (column) values (value);
  2. executemany(批量插入語(yǔ)句)
  • 執(zhí)行多條語(yǔ)句的接口
  • 類似這種: Insert into table_name (column1, column2, column3) values (value1, value2, value3);

具體實(shí)現(xiàn)如下

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

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

這個(gè)簡(jiǎn)單,直接上代碼

  1. cursor.executemany(insert_sql, data_list) 
  2. conn.commit() 
  3. cursor.close() 
  4. conn.close() 

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

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

完整代碼

  1. import pandas as pd  
  2. import numpy as np 
  3.  
  4.  
  5. # pymysql接口 
  6. def mysql_conn(host, userpassword, db, port=3306, charset="utf8"): 
  7.   conn = pymysql.connect(host=host, user=userpassword=passworddatabase=db, port=port, charset=charset) 
  8.   return conn 
  9.  
  10.  
  11. # 當(dāng)前腳本的位置 
  12. current_folder_path = os.path.dirname(__file__) 
  13.  
  14. # 你的文件的位置 
  15. your_file_path1 = os.path.join(current_folder_path, "文件的名字1"
  16. your_file_path2 = os.path.join(current_folder_path, "文件的名字2"
  17.  
  18. # 我這里是以讀取csv文件為例, delimiter為我們內(nèi)部約定的列之間的分割符 
  19. df1 = pd.read_csv(your_file_path1, dtype={"column1": str, "column2": str}, delimiter="/t"
  20. df2 = pd.read_csv(your_file_path2, dtype={"column1": str, "column2": str}, delimiter="/t"
  21. # 合并 
  22. ret_df = pd.merge(df1, df2, left_on=["column_name"], right_on=["column_name"], how="left"
  23.  
  24. # 先創(chuàng)建cursor負(fù)責(zé)操作conn接口 
  25. conn = mysql_conn("your db host""your username""your password""db name"
  26. cursor = conn.cursor() 
  27. # 開啟事務(wù) 
  28. conn.begin() 
  29.  
  30. # 先構(gòu)造需要的或是和數(shù)據(jù)庫(kù)相匹配的列 
  31. columns = list(df.columns) 
  32. # 可以刪除不要的列或者數(shù)據(jù)庫(kù)沒有的列名 
  33. columns.remove("列名"
  34. # 重新構(gòu)造df,用上面的columns,到這里你要保證你所有列都要準(zhǔn)備往數(shù)據(jù)庫(kù)寫入了 
  35. new_df = df[columns].copy() 
  36.  
  37. # 構(gòu)造符合sql語(yǔ)句的列,因?yàn)閟ql語(yǔ)句是帶有逗號(hào)分隔的,(這個(gè)對(duì)應(yīng)上面的sql語(yǔ)句的(column1, column2, column3)) 
  38. columns = ','.join(list(new_df.columns)) 
  39.  
  40. # 構(gòu)造每個(gè)列對(duì)應(yīng)的數(shù)據(jù),對(duì)應(yīng)于上面的((value1, value2, value3)) 
  41. data_list = [tuple(i) for i in gdsord_df.values] # 每個(gè)元組都是一條數(shù)據(jù),根據(jù)df行數(shù)生成多少元組數(shù)據(jù) 
  42.  
  43. # 計(jì)算一行有多少value值需要用字符串占位 
  44. s_count = len(data_list[0]) * "%s," 
  45.  
  46. # 構(gòu)造sql語(yǔ)句 
  47. insert_sql = "insert into " + "數(shù)據(jù)庫(kù)表名" + " (" + columns + ") values (" + s_count[:-1] + ")" 
  48. try: 
  49.   cursor.executemany(insert_sql, data_list) 
  50.   conn.commit() 
  51.   cursor.close() 
  52.   conn.close() 
  53. except Exception as e: 
  54.   # 萬一失敗了,要進(jìn)行回滾操作 
  55.   conn.rollback() 
  56.   cursor.close() 
  57.   conn.close() 

 

責(zé)任編輯:未麗燕 來源: 今日頭條
相關(guān)推薦

2009-11-20 17:06:49

Oracle數(shù)據(jù)庫(kù)字符

2019-11-20 10:38:59

MySQLSQL數(shù)據(jù)庫(kù)

2021-07-15 06:43:11

Bash調(diào)試腳本

2018-11-28 11:20:53

Python函數(shù)式編程編程語(yǔ)言

2011-08-04 18:00:47

SQLite數(shù)據(jù)庫(kù)批量數(shù)據(jù)

2019-07-18 16:32:06

Python函數(shù)數(shù)據(jù)

2018-02-01 14:15:00

Python函數(shù)

2009-11-03 17:15:07

VB.NET開發(fā)Exc

2009-11-20 18:08:37

Oracle數(shù)據(jù)庫(kù)

2020-05-22 10:20:27

Shiro架構(gòu)字符串

2018-06-26 09:37:07

時(shí)序數(shù)據(jù)庫(kù)FacebookNoSQL

2009-11-02 18:07:58

Oracle數(shù)據(jù)庫(kù)

2020-07-21 07:42:29

數(shù)據(jù)庫(kù)信息技術(shù)

2020-05-26 10:42:31

數(shù)據(jù)庫(kù)讀寫分離數(shù)據(jù)庫(kù)架構(gòu)

2025-02-25 07:49:36

智能體數(shù)據(jù)庫(kù)DeepSeek

2023-04-15 20:33:35

圖形數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)

2024-12-04 16:12:31

2016-12-21 15:08:14

數(shù)據(jù)庫(kù)垂直拆分

2023-12-22 09:37:13

二分查找數(shù)組數(shù)據(jù)庫(kù)

2021-07-19 15:33:27

編程Rust開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)