快速MySQL导入

1 投票
2 回答
1430 浏览
提问于 2025-04-18 07:06

我正在写一个脚本,用来把原始数据转换成可以导入MySQL的格式。之前我用的是一个临时的文本文件,后来通过手动的方式,用LOAD DATA INFILE...命令把它导入到数据库里。

现在我把导入的命令放进了Python脚本里:

    db = mysql.connector.connect(user='root', password='root',
                          host='localhost',
                          database='myDB')
    cursor = db.cursor() 
    query = """
    LOAD DATA INFILE 'temp.txt' INTO TABLE myDB.values
    FIELDS TERMINATED BY ',' LINES TERMINATED BY ';';
    """
    cursor.execute(query)
    cursor.close()
    db.commit()
    db.close()

这样做是可以的,但temp.txt文件必须放在数据库的目录下,这对我来说不太方便。

接下来我尝试直接把文件导出并提交:

    db = mysql.connector.connect(user='root', password='root',
                          host='localhost',
                          database='myDB')
    sql = "INSERT INTO values(`timestamp`,`id`,`value`,`status`) VALUES(%s,%s,%s,%s)"
    cursor=db.cursor()

    for line in lines:
        mode, year, julian, time, *values = line.split(",")
        del values[5]
        date = datetime.strptime(year+julian, "%Y%j").strftime("%Y-%m-%d")
        time = datetime.strptime(time.rjust(4, "0"), "%H%M" ).strftime("%H:%M:%S")
        timestamp = "%s %s" % (date, time)
        for i, value in enumerate(values[:20], 1):
            args = (timestamp,str(i+28),value, mode)
            cursor.execute(sql,args)
    db.commit()

这样也能工作,但速度大约慢了四倍,这实在太慢了。(第一版中生成temp.txt时用的也是同样的构造)

我的结论是,我需要一个文件和LOAD DATA INFILE命令来加快速度。为了能自由选择文本文件的位置,LOCAL选项看起来很有用。但是在使用MySQL Connector(1.1.7)时,会遇到一个已知的错误: mysql.connector.errors.ProgrammingError: 1148 (42000): 这个命令在这个MySQL版本中是不允许的。

到目前为止,我发现用MySQLdb代替MySQL Connector可能是个解决办法。不过,MySQLdb的活跃度似乎不高,而且可能永远不会支持Python 3.3。

那么,使用LOAD DATA LOCAL INFILE是否是个好办法?如果是的话,有没有适用于Python 3.3的可用连接器?

编辑:开发完成后,数据库会在服务器上运行,脚本会在客户端运行。

2 个回答

0

要使用 LOAD DATA INFILE 命令来处理你能访问的每一个文件,你需要在建立连接的时候设置 LOCAL_FILES 这个客户端标志。

import mysql.connector
from mysql.connector.constants import ClientFlag
db = mysql.connector.connect(client_flags=[ClientFlag.LOCAL_FILES], <other arguments>)
2

我可能漏掉了什么重要的东西,但难道你不能在第一段代码里直接写上完整的文件名吗?

LOAD DATA INFILE '/full/path/to/temp.txt'

注意,路径必须是服务器上的路径。

撰写回答