[英]Python for loop csv concurrency
我在 80.000 行 + 的大文件中跌跌撞撞,我必須將其保存在我的數據庫中。 將它全部推送到我的 mysql 數據庫需要 20-30 分鍾。 我有一個簡單的 for 循環,它只是循環整個 csv。
import csv
import MySQLdb
# open the connection to the MySQL server.
# using MySQLdb
mydb = MySQLdb.connect(host='hst', user='usr', passwd='pwd', db='db')
cursor = mydb.cursor()
with open('product_de.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=';')
# execute and insert the csv into the database.
for row in csv_reader:
if "PVP_BIG" and "DATE_ADD" in row:
print "First line removed"
else:
print "Not found!"
sql = "INSERT INTO big (SKU,Category,Attribute1,Attribute2,Value1,Value2,Brand,Price,PVP_BIG,PVD,EAN13,WIDTH,HEIGHT,DEPTH,WEIGHT,Stock) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (row[0], row[1],row[3],row[4], row[5],row[6], row[8], row[10], row[11], row[12], row[15], row[16], row[17], row[18], row[19], row[20])
cursor.execute(sql, val)
print row
#close the connection to the database.
#mydb.commit()
cursor.close()
print "CSV has been imported into the database"
有什么方法,我可以把它分成並發,所以根據計算機硬件可能需要3-5分鍾?
首先,通過從內部循環中刪除打印(行),您可以獲得很大的加速。 程序中的其他一切都在等待這個動作,它是一個 IO 動作,可能比你想象的要長得多。 其次,通過批處理 INSERT 語句,您可能會發現顯着的加速,即一次插入多於一行,比如 100 左右。 第三,最好的方法可能是涉及 asyncio,但我對此沒有太多經驗。 您可能會 IO 綁定到 DB 並從 csv 文件中獲取數據,並且永遠不會同時執行這兩項操作,因此我將使用如下簡單的雙線程解決方案:
import csv
import MySQLdb
import threading
from queue import Queue
def row_insert_thread(q: Queue, cursor, mydb):
while True:
command = q.get()
if command is None:
cursor.close()
#mydb.commit()
break
cursor.execute(*command)
mydb = MySQLdb.connect(host='hst', user='usr', passwd='pwd', db='db')
cursor = mydb.cursor()
insert_q = Queue()
row_thread = Thread(target=row_insert_thread,args=(insert_q,cursor,mydb)
row_thread.start()
with open('product_de.csv') as csv_file:
csv_reader = csv.reader(csv_file, delimiter=';')
# execute and insert the csv into the database.
next(csv_reader) #skip the header row I'm assuming there is only one
for row in csv_reader:
sql = "INSERT INTO big (SKU,Category,Attribute1,Attribute2,Value1,Value2,Brand,Price,PVP_BIG,PVD,EAN13,WIDTH,HEIGHT,DEPTH,WEIGHT,Stock) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
val = (row[0], row[1],row[3],row[4], row[5],row[6], row[8], row[10], row[11], row[12], row[15], row[16], row[17], row[18], row[19], row[20])
insert_q.put((sql, val))
print row
#close the connection to the database.
insert_q.put(None)
row_thread.join()
print "CSV has been imported into the database"
對於插入語句,我不習慣 MySQL 從這里的 SQLite 經驗開始,我認為這會起作用:
def insert_multiple_rows(cursor, rows:list):
sql = f"INSERT INTO big (SKU,Category,Attribute1,Attribute2,Value1,Value2,Brand,Price,PVP_BIG,PVD,EAN13,WIDTH,HEIGHT,DEPTH,WEIGHT,Stock) VALUES {'(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s),'*len(rows)}"[:-1]
args = [col for col in [row for row in rows]]
cursor.execute(sql,args)
我希望您可以將它集成到您的代碼中,如果您想使用它,只需更改線程以獲取一個列表,然后在主循環中將值添加到列表中,直到它達到您想要的任何數字或用完行,然后將列表到 insert_q
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.