2014-10-08 7 views
2

나는 MySQL 데이터베이스를 복사하기위한 간단한 파이썬 스크립트를 작성 중이다. 나는 다음과 같은 질문과 그 대답에 기초하여 데이터베이스를 복사하려고 시도하고있다 : "Copy/duplicate database without using mysqldump", "python subprocess and mysqldump"그리고 "Python subprocess, mysqldump and pipes". 그러나 내 스크립트는 테이블과 데이터가 새 데이터베이스에 나타나지 않기 때문에 볼 수없는 몇 가지 이유로 작동하지 않습니다.mysqldump와 mysql을 사용하여 파이썬에서 데이터베이스를 복사하는 방법은 무엇입니까?

내 출력에서 ​​mysqldump가 제대로 작동한다는 것을 알 수 있습니다. (내 출력에서 ​​"완료된 덤프 ..."가 표시됨), 그래서 내 생각에 뭔가 내 파이프 라인에 문제가 있습니다. 당신은 내가 this answer에서 데이터베이스 복사 파이프 라인을했다 볼 수 있듯이

#!/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: "|" 오류가있었습니다. 이제는 두 개의 subprocess.Popen 호출을 제안대로 사용하여 해당 오류 메시지를 해결했습니다.

출력 변수는 mysqldump가 수행되었음을 보여 주지만, mysql 명령에 관해서는 아무 것도 언급되지 않았다.

p2.communicate()as suggested in one answer 대신 p2.wait()p1.wait()을 사용하려고했지만 파이썬 스크립트가 응답하지 않게됩니다. 다음 두 출력 1

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

그러나 같은 mysqldump는 출력을 보여 출력 2 :

은 또한 다음을 시도했다. 그래서 그것은 내 생각에 바보 같은 일이었습니다.

또한 대신 subprocess.call을 사용하려고 시도했지만 스크립트가 응답하지 않게됩니다.

Popen 또는 callshell=True을 포함하면 스크립트가 응답하지 않을 수도 있습니다.

그러나, 명령 프롬프트 (I 윈도우 8.1을 사용) 다음에 명령을 입력하는 작업을 수행 : 3 초 이내에

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

이 복사 내 작은 테스트 데이터베이스.

파이썬에서 작동하도록하고 싶습니다.

답변

9

순수 파이썬의 복사본을 사용하고 싶지만 전체 파이프 작업을 쉘에 위임 할 수는 있습니다.

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

이것은 쉘에서 실행할 때와 같은 방식으로 작동합니다.

p2 = Popen(args1, stdin=p1.stdout, stdout=PIPE, stderr=STDOUT) 

가 읽어야 : 내가 본

2

하나의 문제는이 라인에

p2 = Popen(args2, stdin=p1.stdout, stdout=PIPE, stderr=STDOUT) 

(프로그램이 두 개의 덤프를했다 있도록 args1이, 두 번째 시저에 전달되는되었고, 제로 복원)

1

쉘없이 mysqldump .. | mysql 파이프 라인을 실행할 수있는 방법은 다음과 같습니다.

복잡한 (아마도 비 휴대용) 탈출이 필요한 명령 줄 매개 변수를 전달할 필요가없는 경우
#!/usr/bin/env python 
from subprocess import Popen, PIPE 

mysql = Popen("mysql -h localhost -P 3306 -u root -p mydb2".split(), 
       stdin=PIPE, stdout=PIPE) 
mysqldump = Popen("mysqldump -h localhost -P 3306 -u root -p mydb".split(), 
        stdout=mysql.stdin) 
mysql_stdout = mysql.communicate()[0] 
mysqldump.wait() 

10

How do I use subprocess.Popen to connect multiple processes by pipes?를 참조하십시오, 종료 상태를 캡처, 표준 출력 한 후 여기에 쉘을 사용하는 것이 간단합니다.

+0

우리가 필요하다는 것을 알지 못했습니다 .wait() :) – matiu

+1

@matiu : 좀비 생성을 피하기 위해'mysqldump.wait()'이 호출되었습니다. mysqldump 프로세스 자체는'.wait()'를 호출 할 때 이미 끝났습니다. – jfs