如何在Python中使用mysqldump和mysql复制数据库?

PJv*_*JvG 2 python mysql subprocess mysqldump pymysql

我正在编写一个简单的Python脚本来复制MySQL数据库.我试图根据以下SO问题及其答案复制数据库:" 不使用mysqldump复制/复制数据库 "," python subprocess和mysqldump "和" Python子进程,mysqldump和管道 ".但是,由于某些原因我的脚本无法正常工作,因为表格和数据没有出现在我的新数据库中.

我可以从我的输出中看到mysqldump正常工作(我在输出中看到"转储完成..."),所以我认为我的管道出了问题.

这是我的脚本:

#!/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("Attempting to create new database...")
try:
    cur.execute("CREATE DATABASE mydb2")
    print("Creating new database")
except Exception:
    print("Database already exists")
print()

# close connection just to be sure
cur.close()
conn.close()

print("Trying to copy old database to new database...")

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("output:")
print(output)
print()
Run Code Online (Sandbox Code Playgroud)

如您所见,我从此答案中获取了复制数据库管道.起初我的错误mysqldump: Couldn't find table: "|"其他问题一样.所以现在我subprocess.Popen按照建议使用两个调用,它解决了这个错误信息.

输出变量显示执行了mysqldump,但我没有看到有关mysql命令的任何内容.

我试图使用p2.wait()p1.wait()不是p2.communicate() 在一个答案中建议,但这只是让我的Python脚本变得没有响应.

我也尝试过以下方法:

output1 = p1.communicate()
output2 = p2.communicate()
Run Code Online (Sandbox Code Playgroud)

但是,output1和output2都显示相同的mysqldump输出.所以这只是一个愚蠢的事情我猜...

我也尝试使用subprocess.call而不是subprocess.Popen,但这也使我的脚本变得反应迟钝.

也包括shell=True在任何一个Popen或者call也导致脚本没有响应.

但是,它可以在命令提示符(我使用Windows 8.1)中键入命令,如下所示:

mysqldump -h localhost -P 3306 -u root -p mydb | mysql -h localhost -P 3306 -u root -p mydb2

它在不到三秒的时间内复制我的小型测试数据库.

我希望我也可以在Python中使用它.

dre*_*cat 11

我不知道您想要用于副本的纯Python的程度,但您可以将整个管道操作委托给shell.

subprocess.Popen('mysqldump -h localhost -P 3306 -u -root mydb | mysql -h localhost -P 3306 -u root mydb2', shell=True)
Run Code Online (Sandbox Code Playgroud)

这应该与它在shell上运行时的工作方式相同.


mat*_*tiu 5

我看到的一个问题是在这一行:

p2 = Popen(args1, stdin=p1.stdout, stdout=PIPE, stderr=STDOUT)
Run Code Online (Sandbox Code Playgroud)

它应该是:

p2 = Popen(args2, stdin=p1.stdout, stdout=PIPE, stderr=STDOUT)
Run Code Online (Sandbox Code Playgroud)

(args1 被传递给第二个 proc,因此程序进行了两次转储和零恢复)


小智 5

当我尝试执行相同的任务时,我不断回到这篇文章,我发现这里无响应的原因是 mysql 和 mysqldump 命令中的“-p”开关。“-p”本身意味着“提示输入密码”,因此子进程没有响应,因为它们正在等待密码输入。

以防万一其他人遇到这个古老的线索并试图让它为自己工作,这对我来说是一个错误。