使用Python脚本来源大型MySQL转储

时间:2011-05-13 12:02:02

标签: python database-backups mysql-python

我有一个巨大的(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 module不支持the source command

EDITED

文件包含一堆insert和create语句。失败的地方在于包含原始文本的大型表的插入。原始文本中有各种各样的分号和换行符,因此很难根据它来分割命令。

3 个答案:

答案 0 :(得分:2)

你有什么理由不能为你做出一个过程吗?

import subprocess

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

您可能希望稍微调整一下,因为密码将暴露给ps。

答案 1 :(得分: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行。

答案 2 :(得分:0)

我认为,有时候,我们应该选择其他方式来有效地完成这项工作。我更喜欢将这些内容用于大数据:http://www.mysqldumper.net/