PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Python psql \copy CSV to remote server

Versuchen Sie, shell=True nicht zu verwenden wenn du es vermeiden kannst. es ist besser, den Befehl selbst zu tokenisieren, um sh zu helfen.

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

In diesem Fall könnte Ihre Copy-Anweisung so sein, wie sie wörtlich an psql übergeben wird, da es keine Shell gibt Zitat Probleme zu berücksichtigen. (Anmerkung:Für Python muss dies noch in Anführungszeichen gesetzt werden, damit die Zeichenfolge unverändert bleibt).

Wenn Sie trotzdem shell=True verwenden möchten dann müssen Sie das String-Literal für Python und maskieren Schale

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

erstellt eine Zeichenfolge in Python, die

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

Und genau das haben wir als erstes für unsere Shell herausgefunden!

Bearbeiten (klärt etwas aus den Kommentaren):

subprocess.call , wenn shell=True nicht verwendet wird , nimmt eine iterable von Argumenten.

Also hättest du

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)

Siehe https://docs.python.org/2/library/ subprocess.html#subprocess.call oder https://docs.python.org/3/library/ subprocess.html#subprocess.call

zusätzliche Bearbeitung:- Bitte beachten Sie, dass Sie die hier beschriebene Methode verwenden sollten, um eine Shell-Injektion zu vermeiden. Siehe den Warnabschnitt von https://docs.python. org/2/library/subprocess.html#frequently-used-arguments