使用Python脚本导入大型MySQL转储

0 投票
3 回答
3410 浏览
提问于 2025-04-16 17:34

我有一个很大的数据库备份文件(超过1GB),我想把它加载到其他服务器的新数据库里。我试着一行一行地解析这个文件,然后把每一行都执行到mysql里,但不幸的是,这样分割出来的命令并不完整,导致执行失败。

filename='/var/test.sql'
fp = open(filename)
while True:
        a = fp.readline()
        if not a:
           break
        cursor.execute(a) #fails most of the time

而且,这个文件太大了,无法一次性全部加载到内存中。此外,python的MySQLdb模块也不支持source命令

编辑

这个文件里包含了很多插入和创建的语句。出问题的地方主要是在插入那些包含大量原始文本的大表时。因为原始文本里有各种分号和换行符,所以很难根据这些来正确分割命令。

3 个回答

0

我觉得,有时候我们应该选择其他的方法来更有效地完成工作。我更喜欢用这个工具来处理大数据:http://www.mysqldumper.net/

1

假设查询都是在行的边界结束的,你可以把行加在一起,直到它们组成一个完整的查询。

像这样:

filename='/var/test.sql'
fp = open(filename)
lines = ''
while True:
        a = fp.readline()
        if not a:
           break
        try:
           cursor.execute(lines + a)
           lines = ''
        except e:
           lines += a

如果只是插入语句,你可以找那些以分号(;)结尾的行,然后下一行是以“INSERT”开头的。

filename='/var/test.sql'
fp = open(filename)
lines = ''
while True:
        a = fp.readline()
        if not a:
           break
        if lines.strip().endswith(';') and a.startswith('insert'):
           cursor.execute(lines)
           lines = a
        else:
           lines += a
# Catch the last one
cursor.execute(lines)

编辑:把 trim() 替换成了 strip(),并且意识到在第二个代码示例中我们不需要执行行 a

1

有没有什么原因让你不能开一个新进程来帮你完成这个任务呢?

import subprocess

fd = open(filename, 'r')
subprocess.Popen(['mysql', '-u', username, '-p{}'.format(password), '-h', hostname, database], stdin=fd).wait()

你可能需要稍微调整一下,因为密码会在ps命令中暴露出来。

撰写回答