sql >> Base de Datos >  >> RDS >> PostgreSQL

Python psql \copiar CSV al servidor remoto

Trate de no usar shell=True si puedes evitarlo. es mejor tokenizar el comando usted mismo para ayudar a sh.

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

En este caso, su declaración de copia podría ser tal como se pasa a psql textualmente, porque no hay shell citando cuestiones a tener en cuenta. (N.B. todavía tengo que citar esto para python, por lo que la cadena permanecería como está).

Si aún desea usar shell=True entonces tienes que escapar del literal de cadena tanto para python como para concha

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

creará una cadena en python que será

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

¡Que es lo que descubrimos que necesitábamos en nuestro caparazón en primer lugar!

Editar (aclarando algo de los comentarios):

subprocess.call , cuando no se usa shell=True , toma un iterable de argumentos.

Entonces podrías tener

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)

Consulte https://docs.python.org/2/library/ subproceso.html#subproceso.llamar o https://docs.python.org/3/library/ subproceso.html#subproceso.llamar

edición adicional:- Tenga en cuenta que para evitar la inyección de shell, debe utilizar el método descrito aquí. Consulte la sección de advertencia de https://docs.python. org/2/library/subprocess.html#frequently-used-arguments