PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Python psql \copy CSV sur le serveur distant

Essayez de ne pas utiliser shell=True si vous pouvez l'éviter. mieux vaut tokeniser la commande vous-même pour aider sh.

subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])

Dans ce cas, votre déclaration de copie pourrait être telle qu'elle est transmise textuellement à psql, car il n'y a pas de shell citant les problèmes à prendre en compte. (N.B. il faut toujours citer ceci pour python, donc la chaîne resterait telle quelle).

Si vous souhaitez toujours utiliser shell=True alors vous devez échapper la chaîne littérale pour python et coquille

"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""

créera une chaîne en python qui sera

"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"

C'est ce dont nous avions besoin sur notre shell en premier lieu !

Modifier (clarifiant quelque chose à partir des commentaires) :

subprocess.call , lorsqu'il n'utilise pas shell=True , prend un itérable d'arguments.

Vous pourriez donc avoir

psql_command = "\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""
# user, hostname, password, dbname all defined elsewhere above.
command = ["psql",
    "-U", user,
    "-h", hostname,
    "-d", dbname,
    "-w", password,
    "-c", psql_command,
]

subprocess.call(command)

Voir https://docs.python.org/2/library/ subprocess.html#subprocess.appel ou https://docs.python.org/3/library/ subprocess.html#subprocess.appel

édition supplémentaire :- Veuillez noter que pour éviter l'injection de shell, vous devez utiliser la méthode décrite ici. Consultez la section d'avertissement de https://docs.python. org/2/library/subprocess.html#frequently-used-arguments