Comment copier une base de données avec la commande mysqldump et mysql en Python?
Je suis en train d'écrire un simple script Python pour copier une base de données MySQL. Je suis tenter de copier la base de données basée sur le suivant de SORTE que les questions et leurs réponses: "Copie/dupliquer la base de données sans l'aide de la commande mysqldump", "python sous-processus et mysqldump" et "Python sous-processus, mysqldump, et des tuyaux". Cependant, mon script ne fonctionne pas pour une raison que je ne peut pas voir que les tables et les données n'apparaissent pas dans ma nouvelle base de données.
Je peux voir de ma sortie de la commande mysqldump fonctionne correctement (je vois un "Dump terminée sur..." dans ma sortie), donc je pense que quelque chose de mal avec mon pipeline.
Voici mon script:
#!/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()
Comme vous pouvez le voir, j'ai pris la copie de base de données pipeline de cette réponse. Et j'ai d'abord eu l'erreur mysqldump: Couldn't find table: "|"
comme dans que d'autres question. Alors maintenant, j'utilise deux subprocess.Popen
appels comme suggéré de résoudre ce message d'erreur.
La variable de sortie montre qu'un mysqldump est effectuée, mais je ne vois rien n'est mentionné au sujet de la commande mysql.
J'ai essayé d'utiliser p2.wait()
et p1.wait()
au lieu de p2.communicate()
comme le suggère l'une réponse, mais qui fait juste mon script Python ne répond plus.
J'ai aussi essayé le suivant:
output1 = p1.communicate()
output2 = p2.communicate()
Mais les deux output1 et output2 montrent la même mysqldump sortie. C'était donc juste une chose stupide à faire, je suppose..
J'ai aussi essayé d'utiliser subprocess.call
au lieu de subprocess.Popen
, mais qui fait aussi mon script ne répond plus.
Aussi, y compris shell=True
dans Popen
ou call
aussi des résultats dans le script juste de répondre.
Cependant, c'est de taper la commande dans la invite de commande (j'utilise Windows 8.1) comme suit:
mysqldump -h localhost -P 3306 -u root -p mydb | mysql -h localhost -P 3306 -u root -p mydb2
Il copie mon petit test de la base de données en moins de trois secondes.
Je souhaite que je pourrais aussi le faire fonctionner en Python.
OriginalL'auteur PJvG | 2014-10-08
Vous devez vous connecter pour publier un commentaire.
Je ne connais pas le degré de pur Python vous souhaitez utiliser pour la copie, mais vous pouvez simplement déléguer l'ensemble de tuyau de fonctionnement de la coquille.
Cela devrait fonctionner de la même façon que lorsque vous l'exécutez sur la coque.
OriginalL'auteur dreyescat
Un problème que j'ai vu est sur cette ligne:
Il faut lire:
(args1 ont été passés à la deuxième proc, de sorte que le programme ne s'deux dumps et zéro restaure)
OriginalL'auteur matiu
Voici comment vous pouvez exécuter
mysqldump .. | mysql
pipeline sans la coquille:Voir Comment puis-je utiliser des sous-processus.Popen de connecter plusieurs processus par des tuyaux?
Si vous n'avez pas besoin de passer des paramètres de ligne de commande qui nécessitent complexe (peut-être non portable), l'évasion, la capture de la sortie statuts, stdout, alors il est plus simple d'utiliser le shell ici.
est appelé à éviter la création d'un zombie. Le
mysqldump
processus lui-même a déjà fini le temps de nous appeler.wait()
.OriginalL'auteur jfs