Řešení v přijaté odpovědi bude fungovat pouze na serveru a když uživatel provádějící dotaz bude mít oprávnění číst soubor, jak je vysvětleno v této odpovědi SO.
Jinak je flexibilnějším přístupem nahradit COPY
SQL příkaz s psql
"metapříkaz" s názvem \copy
který má všechny stejné možnosti jako "skutečná" COPY, ale je spuštěn uvnitř klienta (bez potřeby ;
na konci):
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
Podle dokumentů \copy
příkaz:
Provádí frontendovou (klientskou) kopii. Toto je operace, která spouští příkaz SQL COPY, ale místo toho, aby server četl nebo zapisoval zadaný soubor, psql čte nebo zapisuje soubor a směruje data mezi serverem a místním systémem souborů. To znamená, že přístupnost a oprávnění k souborům patří místnímu uživateli, nikoli serveru, a nejsou vyžadována žádná oprávnění superuživatele SQL.
Kromě toho, pokud the_file.csv
obsahuje záhlaví v prvním řádku, lze jej rozpoznat přidáním header
na konci výše uvedeného příkazu:
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv header"
Jak je uvedeno v dokumentaci PostgreSQL (II. Klientské aplikace PostgreSQL - psql), můžete předat příkaz do psql
(PostgreSQL interaktivní terminál) s přepínačem -c
. Vaše možnosti jsou:
1, CSV na straně klienta:\copy
meta-příkaz
proveďte SQL COPY
ale soubor je načten na klientovi a obsah je směrován na server.
psql -c "\copy tbname FROM '/tmp/the_file.csv' delimiter '|' csv"
(možnost na straně klienta původně zmíněná v této odpovědi)
2. CSV na straně serveru:SQL COPY
příkaz
čte soubor na serveru (aktuální uživatel musí mít potřebná oprávnění):
psql -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"
role DB potřebné pro čtení souboru na serveru:
COPY
pojmenování souboru nebo příkazu je povoleno pouze superuživatelům databáze nebo uživatelům, kteří mají přidělenou jednu z výchozích rolípg_read_server_files
,pg_write_server_files
nebopg_execute_server_program
také proces serveru PostgreSQL musí mít přístup k souboru.
Nejflexibilnějším způsobem je použití shellu HERE document
, což vám umožňuje používat proměnné prostředí uvnitř dotazu, dokonce i uvnitř (dvojitých nebo jednoduchých) uvozovek:
#!/bin/sh
THE_USER=moi
THE_DB=stuff
THE_TABLE=personnel
PSQL=/opt/postgresql/bin/psql
THE_DIR=/tmp
THE_FILE=the_file.csv
${PSQL} -U ${THE_USER} ${THE_DB} <<OMG
COPY ${THE_TABLE} FROM '${THE_DIR}/${THE_FILE}' delimiter '|' csv;
OMG
K dokončení předchozí odpovědi bych navrhl:
psql -d your_dbname --user=db_username -c "COPY tbname FROM '/tmp/the_file.csv' delimiter '|' csv;"