使用python连接器加速缓慢的MySQL导入

waxmsbnn  于 2023-02-11  发布在  Python
关注(0)|答案(1)|浏览(108)

我正在写一个python脚本,用来将一个大型数据库导入MySQL。到目前为止,我使用了这种方法,它工作正常,但速度很慢:

importdb = "mysql -h " + DB_HOST + " -u " + DB_USER + " -p" + shlex.quote(DB_USER_PASSWORD) + " " + DB_TARGET + " < " + os.getcwd() + "\\AllPrintings.sql"
os.system(importdb)

根据this和类似的帖子,如果在导入之前更改默认设置,导入可以更快:

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;
# <import statement here>
COMMIT;
SET unique_checks=1;
SET foreign_key_checks=1;

问题是这些设置只与特定的连接相关。当我使用Python脚本时,我看到两个选项,在这两个选项中我都找不到有效的解决方案:
1.使用os.system并添加SET命令-我尝试用来分隔命令;但似乎在第一次之后就停止执行了

不起作用

importdb = "mysql -h " + DB_HOST + " -u " + DB_USER + " -p" + shlex.quote(DB_USER_PASSWORD)+ "; " + "use " + DB_TARGET + "; SET autocommit=0; SET unique_checks=0; SET FOREIGN_KEY_CHECKS=0; " + "source" + os.getcwd() + "\\AllPrintings.sql; SET autocommit=1; SET unique_checks=1; SET FOREIGN_KEY_CHECKS=1;"
os.system(importdb)

1.使用import mysql.connector并添加import语句:SET命令有效,但不能导入

不起作用

cur.execute(f"SET autocommit=0;")
cur.execute(f"SET unique_checks=0;")
cur.execute(f"SET FOREIGN_KEY_CHECKS=0;")
cur.execute(DB_TARGET + ' < ' + os.getcwd() + '\\AllPrintings.sql')
conn.commit()
cur.execute(f"SET autocommit=1;")
cur.execute(f"SET unique_checks=1;")
cur.execute(f"SET FOREIGN_KEY_CHECKS=1;");

我被困住了,不知道该怎么继续前进,我很感激所有的帮助...

编辑和解决方案

在下面@mrrobot.viewsource回答的基础上,解决方案是用上面的命令修改导入的db,将测试数据库的导入时间从73分钟减少到2分钟。

with open(os.getcwd() + "\\AllPrintings.sql", "r+",encoding="utf8") as f:
        content = f.read()
        f.seek(0, 0)
        f.write("SET autocommit=0;\nSET unique_checks=0;\nSET FOREIGN_KEY_CHECKS=0;" + '\n' + content)

with open(os.getcwd() + "\\AllPrintings.sql", "a+", encoding="utf8") as f:
    f.write("\nSET unique_checks=1;\nSET FOREIGN_KEY_CHECKS=1;\n")
oyjwcjzk

oyjwcjzk1#

你的代码有一些问题。你试过打印变量importdb吗?下面是你的脚本中发生的事情:

    • 问题:**

您的脚本(出于显而易见的原因注解os.system(importdb)):

import shlex
import os

DB_HOST="1.1.1.1"
DB_USER="root"
DB_USER_PASSWORD="password"
DB_TARGET="somedb"

importdb = "mysql -h " + DB_HOST + " -u " + DB_USER + " -p" + shlex.quote(DB_USER_PASSWORD)+ "; " + "use " + DB_TARGET + "; SET autocommit=0; SET unique_checks=0; SET FOREIGN_KEY_CHECKS=0; " + "source" + os.getcwd() + "\\AllPrintings.sql; SET autocommit=1; SET unique_checks=1; SET FOREIGN_KEY_CHECKS=1;"
print(importdb)
#os.system(importdb)

输出:

mysql -h 1.1.1.1 -u root -ppassword; use somedb; SET autocommit=0; SET unique_checks=0; SET FOREIGN_KEY_CHECKS=0; source/some/path\AllPrintings.sql; SET autocommit=1; SET unique_checks=1; SET FOREIGN_KEY_CHECKS=1;

从输出中:
1.第一个;(即mysql -h 1.1.1.1 -u root -ppassword;)使控件转到MySQL客户端shell,您不再使用python来回答以下查询。
但似乎在第一次之后就停止执行了
1.如果您检查输出source/some/path\AllPrintings.sql;-源代码和文件名之间应该有空格。

  1. SET命令必须存在于AllPrintings.sql文件中,如下所示:
# <AllPrintings.sql - start of file>

SET autocommit=0;
SET unique_checks=0;
SET foreign_key_checks=0;

# <your_queries in the sql file>

COMMIT;
SET unique_checks=1;
SET foreign_key_checks=1;

# <AllPrintings.sql - end of file>
    • 解决方案:**

在AllPrintings.sql文件中添加SET命令(如第3点所述),并按如下所示更改importdb变量

importdb = "mysql -h " + DB_HOST + " -u " + DB_USER + " -p" + shlex.quote(DB_USER_PASSWORD)+ " -D " + DB_TARGET + " < " + os.getcwd() + "\\AllPrintings.sql"

你应该能行。

相关问题