4

MySQL データベースをコピーするための簡単な Python スクリプトを作成しています。次のSOの質問とその回答に基づいてデータベースをコピーしようとしています:「mysqldumpを使用せずにデータベースをコピー/複製する」、「pythonサブプロセスとmysqldump」、および「Pythonサブプロセス、mysqldumpとパイプ」。ただし、新しいデータベースにテーブルとデータが表示されないため、何らかの理由でスクリプトが機能しません。

出力から、mysqldump が正しく機能していることがわかります (出力に「Dump completed on...」が表示されます) 。パイプラインに何か問題があると思います。

これが私のスクリプトです:

#!/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()

ご覧のとおり、この回答からコピー データベース パイプラインを取得しました。そして、最初は他の質問とmysqldump: Couldn't find table: "|"同じようにエラーが発生しました。そのため、提案どおりに2つの呼び出しを使用して、そのエラーメッセージを解決しました。subprocess.Popen

出力変数は、mysqldump が実行されたことを示していますが、mysql コマンドについては何も言及されていません。

1つの回答で提案されているのではなくp2.wait()andを使用しようとしましたが、Pythonスクリプトが応答しなくなります。p1.wait()p2.communicate()

私も次のことを試しました:

output1 = p1.communicate()
output2 = p2.communicate()

しかし、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

私の小さなテスト データベースを 3 秒以内にコピーします。

Pythonでも動作するようにできたらいいのにと思います。

4

4 に答える 4

15

コピーに使用する純粋な Pythonの程度はわかりませんが、パイプ操作全体をシェルに委譲することができます。

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

これは、シェルで実行したときと同じように機能するはずです。

于 2014-10-08T20:53:57.547 に答える