如何使用Python中的mysqldump和mysql复制数据库?
如何使用Python中的mysqldump和mysql复制数据库?
我正在编写一个简单的Python脚本来复制一个MySQL数据库。我试图根据以下SO问题和它们的答案来复制数据库: \"Copy/duplicate database without using mysqldump\", \"python subprocess and mysqldump\"和\"Python subprocess, mysqldump and pipes\"。然而,我的脚本由于某种我看不到的原因而无法工作,因为表和数据没有出现在我的新数据库中。\n从输出中我可以看到mysqldump正常工作(我在输出中看到\"Dump completed on...\"),所以我认为我的管道有问题。\n这是我的脚本:\n
#!/usr/bin/env python import pymysql from subprocess import Popen, PIPE, STDOUT conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='mydb') cur = conn.cursor() print("尝试创建新数据库...") try: cur.execute("CREATE DATABASE mydb2") print("正在创建新数据库") except Exception: print("数据库已经存在") print() # 关闭连接以确保安全 cur.close() conn.close() print("尝试将旧数据库复制到新数据库...") args1 = ["mysqldump", "-h", "localhost", "-P", "3306", "-u", "root", "-p", "mydb"] args2 = ["mysql", "-h", "localhost", "-P", "3306", "-u", "root", "-p", "mydb2"] p1 = Popen(args1, stdout=PIPE, stderr=STDOUT) p2 = Popen(args1, stdin=p1.stdout, stdout=PIPE, stderr=STDOUT) output = p2.communicate() print("输出:") print(output) print()
\n如你所见,我从这个答案中获取了复制数据库的管道。起初,我有错误mysqldump: Couldn\'t find table: \"|\"
,就像那个问题中所描述的一样。所以现在我使用了两个subprocess.Popen
调用,解决了那个错误信息。\n输出变量显示进行了mysqldump操作,但我没有看到有任何关于mysql命令的提及。\n我尝试使用p2.wait()
和p1.wait()
代替p2.communicate()
,如一个答案中建议的,但这只会导致我的Python脚本无响应。\n我还尝试了以下操作:\n
output1 = p1.communicate() output2 = p2.communicate()
\n但是output1和output2都显示相同的mysqldump输出。所以这只是一个愚蠢的事情我猜..\n我还尝试使用subprocess.call
而不是subprocess.Popen
,但这也导致我的脚本无响应。\n同时在Popen
或call
中包括shell=True
也导致脚本无响应。\n然而,在命令提示符中输入以下命令是可以工作的(我使用的是Windows 8.1):\nmysqldump -h localhost -P 3306 -u root -p mydb | mysql -h localhost -P 3306 -u root -p mydb2
\n它在不到三秒钟的时间内复制了我的小型测试数据库。\n我希望我也能让它在Python中工作。
问题原因:在使用mysql和mysqldump命令时,使用了"-p"选项,这个选项表示提示输入密码,所以子进程一直等待密码输入而导致无响应。
解决方法:在使用mysql和mysqldump命令时,去掉"-p"选项,或者在命令中直接指定密码,这样就不会出现等待密码输入而导致无响应的情况。
下面是示例代码:
import os # 导出数据库 def export_database(): host = "localhost" user = "root" password = "123456" database = "mydatabase" export_file = "backup.sql" # 构造导出命令 command = f"mysqldump -h {host} -u {user} -p{password} {database} > {export_file}" # 执行导出命令 os.system(command) print("Database exported successfully.") # 导入数据库 def import_database(): host = "localhost" user = "root" password = "123456" database = "mydatabase" import_file = "backup.sql" # 构造导入命令 command = f"mysql -h {host} -u {user} -p{password} {database} < {import_file}" # 执行导入命令 os.system(command) print("Database imported successfully.") # 导出数据库 export_database() # 导入数据库 import_database()
注意:在实际使用时,需要根据自己的数据库配置进行相应的修改。
问题的出现原因是用户想要在Python中使用mysqldump和mysql进行数据库的复制,但不清楚应该如何操作。解决方法是将整个管道操作委托给shell,使用subprocess模块的Popen函数来执行命令。具体的代码如下:
import subprocess subprocess.Popen('mysqldump -h localhost -P 3306 -u -root mydb | mysql -h localhost -P 3306 -u root mydb2', shell=True)
这段代码会在shell中执行相同的操作。
很奇怪的是,使用SQL无法简单地复制一个数据库,这显然是一个有意为之的选择,但为什么呢?