COPY
die Datei in eine temporäre Staging-Tabelle und aktualisieren Sie die tatsächliche Tabelle von dort. Mögen:
CREATE TEMP TABLE tmp_x (id int, apple text, banana text);
COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE tbl
SET banana = tmp_x.banana
FROM tmp_x
WHERE tbl.id = tmp_x.id;
DROP TABLE tmp_x;
Wenn die importierte Tabelle genau mit der zu aktualisierenden Tabelle übereinstimmt, kann dies praktisch sein:
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
Erstellt eine leere temporäre Tabelle, die ohne Einschränkungen der Struktur der vorhandenen Tabelle entspricht.
Privilegien
SQL COPY
erfordert hierfür Superuser-Berechtigungen. ( Das Handbuch ):
COPY
Das Benennen einer Datei oder eines Befehls ist nur Datenbank-Superusern gestattet, da damit jede Datei gelesen oder geschrieben werden kann, auf die der Server zugreifen darf.
Der psql Meta-Befehl \copy
funktioniert für jede db Rolle. Das Handbuch:
Führt eine Frontend-Kopie (Client) durch. Dies ist eine Operation, die einen SQL- COPY
Befehl ausführt. Statt dass der Server die angegebene Datei liest oder schreibt, liest oder schreibt psql die Datei und leitet die Daten zwischen dem Server und dem lokalen Dateisystem weiter. Dies bedeutet, dass Dateizugriff und Berechtigungen die des lokalen Benutzers und nicht des Servers sind und keine SQL-Superuser-Berechtigungen erforderlich sind.
Der Umfang temporärer Tabellen ist auf eine einzelne Sitzung einer einzelnen Rolle beschränkt, daher muss das oben Gesagte in derselben psql-Sitzung ausgeführt werden:
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
Wenn Sie dies in einem Bash-Befehl skripten, müssen Sie alles in einem einzigen psql-Aufruf zusammenfassen. Mögen:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
Normalerweise benötigen Sie den Meta-Befehl \\
, um zwischen psql-Meta-Befehlen und SQL-Befehlen in psql zu wechseln. Dies ist jedoch \copy
eine Ausnahme von dieser Regel. Das Handbuch noch einmal:
Für den \copy
Meta-Befehl gelten spezielle Parsing-Regeln . Im Gegensatz zu den meisten anderen Meta-Befehlen wird der gesamte Rest der Zeile immer als Argument von angesehen \copy
, und in den Argumenten werden weder Variableninterpolation noch Backquote-Erweiterung durchgeführt.
Große Tische
Wenn die Importtabelle groß ist, kann es sich lohnen, temp_buffers
die Sitzung vorübergehend zu erhöhen (als erstes in der Sitzung):
SET temp_buffers = '500MB';
Fügen Sie der temporären Tabelle einen Index hinzu:
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
Und ANALYZE
manuell ausführen , da temporäre Tabellen nicht durch Autovakuum / Autoanalyse abgedeckt werden.
ANALYZE tmp_x;
Verwandte Antworten: