我正在尝试处理超过1GB的文本文件,并使用python将数据保存到Mysql数据库中。
我在下面粘贴了一些示例代码
import os
import MySQLdb as mdb
conn = mdb.connect(user='root', passwd='redhat', db='Xml_Data', host='localhost', charset="utf8")
file_path = "/home/local/user/Main/Module-1.0.4/file_processing/part-00000.txt"
file_open = open('part-00000','r')
for line in file_open:
result_words = line.split('\t')
query = "insert into PerformaceReport (campaignID, keywordID, keyword, avgPosition)"
query += " VALUES (%s,%s,'%s',%s) " % (result_words[0],result_words[1],result_words[2],result_words[3])
cursor = conn.cursor()
cursor.execute( query )
conn.commit()
实际上插入数据的列数超过18列,我刚刚粘贴了四列(例如)
因此,当我运行上面的代码时,执行时间会花费一些hours
我所有的怀疑都是
已编辑的代码
query += " VALUES (%s,%s,'%s',%s) " % (int(result_words[0] if result_words[0] != '' else ''),int(result_words[2] if result_words[2] != '' else ''),result_words[3] if result_words[3] != '' else '',result_words[4] if result_words[4] != '' else '')
实际上我正在以上述格式提交值(通过检查结果存在)
答案 0 :(得分:5)
有点猜测,但我会说文件中每行的conn.commit()
都会产生很大的不同。尝试将其移出循环。您也不需要在循环的每次迭代中重新创建游标 - 只需在循环之前执行一次。
答案 1 :(得分:2)
除了蒂姆所说的,我还会看看MySQL的LOAD DATA INFILE。在Python中进行任何必要的预处理并将其写入MySQL可以访问的单独文件,然后执行适当的查询并让MySQL进行加载。
或者,可能会将Python代码重写为它应该是什么(您应该将参数作为值传递,而不是执行字符串操作 - 对一个SQL注入攻击):
query = 'insert into something(a, b, c, d) values(%s, %s, %s, %s)'
with open('file.tab') as fin:
values = (row.split('\t')[:4] for row in fin)
cursor.executemany(query, values)
答案 2 :(得分:0)
import os
import MySQLdb as mdb
import csv
def read_file():
file_path = "/home/local/user/Main/Module-1.0.4/file_processing/part-00000.txt"
with open('part-00000','r') as infile:
file_open= csv.reader(infile, delimiter='\t')
cache = []
for line in file_open:
cache.append(line)
if len(cache) > 500:
yield cache
cache = []
yield cache
conn = mdb.connect(user='root', passwd='redhat', db='Xml_Data', host='localhost', charset="utf8")
cursor = conn.cursor()
query = "insert into PerformaceReport (campaignID, keywordID, keyword, avgPosition) VALUES (%s,%s,%s,%s)"
for rows in read_file():
try:
cursor.executemany(query, rows)
except mdb.Error:
conn.rollback()
else:
conn.commit()
代码未经测试且可能包含轻微错误,但应该更快,但不如使用LOAD DATA INFILE
快。