PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Python psql \copy CSV para servidor remoto


Tente não usar shell=True se puder evitá-lo. melhor tokenizar o comando você mesmo para ajudar sh.
subprocess.call(["psql", "-U", "{user}", "-h", "{ip}", "-d", "{db}", "-w", "{pw}", "-c", "{copy statement}"])

Nesse caso, sua instrução de cópia pode ser passada para o psql literalmente, porque não há shell citando questões a serem levadas em consideração. (N.B. ainda precisa citar isso para python, para que a string permaneça como está).

Se você ainda quiser usar shell=True então você tem que escapar da string literal para python e Concha
"\"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\\\"' NULL ''\""

irá criar uma string em python que será
"\copy table (col1, col2) FROM file_location CSV HEADER QUOTE '\"' NULL ''\"

Que é o que descobrimos que precisávamos em nosso shell em primeiro lugar!

Editar (esclarecendo algo dos comentários):

subprocess.call , quando não estiver usando shell=True , recebe um iterável de argumentos.

Então você poderia ter
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/ subprocess.html#subprocess.call ou https://docs.python.org/3/library/ subprocess.html#subprocess.call

edição extra:- Observe que, para evitar a injeção de shell, você deve usar o método descrito aqui. Consulte a seção de aviso de https://docs.python. org/2/library/subprocess.html#frequently-used-arguments