0

我正在尝试处理超过 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 列,我只粘贴了 4 列(例如)

所以当我运行上面的代码时,执行时间需要一些hours

我所有的疑惑都是

  1. 有没有其他方法可以非常快速地处理 python 中的 1GB 文本文件?
  2. 是否有任何框架可以处理 1GB 文本文件并将数据快速保存到数据库中?
  3. 如何在几分钟内(有可能)处理大尺寸(1GB)的文本文件并将数据保存到数据库中?我所关心的是,我们需要尽可能快地处理 1GB 文件,而不是几个小时。

编辑代码

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 '')

实际上我以上述格式提交值(通过检查结果存在)

4

3 回答 3

5

有点疯狂的猜测,但我会说conn.commit()文件中的每一行都会产生很大的不同。尝试将其移出循环。您也不需要在循环的每次迭代中重新创建光标 - 只需在循环之前执行一次。

于 2012-11-19T10:08:56.917 回答
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)
于 2012-11-19T10:12:01.863 回答
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

于 2012-11-19T10:22:45.667 回答