Working with Import and Export

1. Using COPY TO

COPY orders TO '/var/lib/postgresql/exports/orders.csv'
   WITH (FORMAT csv, HEADER true);

2. Using COPY FROM

COPY orders FROM '/var/lib/postgresql/imports/orders.csv'
   WITH (FORMAT csv, HEADER true);

3. Specifying Delimiter

COPY t FROM '/tmp/in.tsv' WITH (FORMAT text, DELIMITER E'\t');

4. Using CSV Format

COPY t TO '/tmp/out.csv' WITH (FORMAT csv, HEADER true, QUOTE '"', ESCAPE '"');

5. Using HEADER Option

COPY t FROM '/tmp/in.csv' WITH (FORMAT csv, HEADER match);  -- PG 16+: validate header

6. Handling NULL Values

COPY t TO '/tmp/out.csv' WITH (FORMAT csv, NULL '\N');
COPY t FROM '/tmp/in.csv' WITH (FORMAT csv, NULL '');

7. Using Quote Character

COPY t TO STDOUT WITH (FORMAT csv, QUOTE '''', FORCE_QUOTE *);

8. Using Escape Character (ESCAPE '\')

COPY t FROM '/tmp/in.csv' WITH (FORMAT csv, ESCAPE '\');

9. Using \copy Command

psql -c "\copy orders TO 'orders.csv' WITH (FORMAT csv, HEADER true)"
COPY\copy
Server-side pathClient-side path
Needs superuser/pg_read_server_filesUses client privileges

10. Using PROGRAM Option

COPY t FROM PROGRAM 'gunzip -c /imports/big.csv.gz' WITH (FORMAT csv, HEADER true);
COPY t TO   PROGRAM 'gzip -9 > /exports/big.csv.gz' WITH (FORMAT csv, HEADER true);
Warning: PROGRAM runs OS commands as the postgres user. Restrict access carefully.

11. Importing JSON Data

CREATE TEMP TABLE raw (j jsonb);
\copy raw FROM 'events.jsonl' (FORMAT csv, QUOTE E'\b', DELIMITER E'\b');
INSERT INTO events SELECT (j->>'id')::int, j->>'name', j FROM raw;

12. Exporting Query Results

COPY (SELECT id, total_cents FROM orders WHERE status='paid')
  TO '/tmp/paid.csv' WITH (FORMAT csv, HEADER true);

13. Using STDIN and STDOUT

psql -c "COPY t TO STDOUT WITH (FORMAT csv, HEADER true)" > out.csv
cat in.csv | psql -c "COPY t FROM STDIN WITH (FORMAT csv, HEADER true)"

14. Handling Large Files

TipDetail
Drop indexesRecreate after load
Disable triggersALTER TABLE ... DISABLE TRIGGER USER
Use UNLOGGEDStage table then INSERT INTO real table
maintenance_work_memBoost for post-load index build
synchronous_commit=off(session) during bulk load