COPY is PostgreSQL’s high-performance bulk data loader and dumper. It can read data from a file, the operating-system program output, or the client’s standard input (STDIN) and insert it directly into a table, or write table/query results to a file, program, or standard output (STDOUT). COPY bypasses much of the SQL executor overhead by streaming rows straight to or from the storage layer, making it dramatically faster than many single-row INSERT or SELECT operations.Key behaviors- Operates in a single transaction by default; failure rolls back the whole operation.- Accepts many format options: CSV, TEXT, BINARY. CSV handling supports custom delimiters, quote, escape, header rows, and NULL representations.- Supports column lists so you can load/export subsets of columns.- Works with queries via COPY (SELECT ...) TO allowing fast ad-hoc exports.- Requires superuser or table ownership when accessing server-side files. Client-side use requires the psql meta-command \copy or STDIN/STDOUT.Caveats- Constraints and triggers fire normally; disable them or load into a staging table for maximum speed.- COPY cannot reference foreign tables or views directly (wrap in a SELECT).- Server-side paths are resolved relative to the database server, not the client machine.
table_name
(identifier) - Target or source table.column_list
(list) - Optional subset of columns.FROM / TO
(keyword) - Direction of data movement.filename
(text) - Absolute or relative server-side path.PROGRAM
(text) - Shell command executed by server.STDIN / STDOUT
(keyword) - Use client’s standard streams.FORMAT
(enum) - csv, text, or binary.DELIMITER
(char) - Field separator (default TAB for text, comma for csv).NULL
(text) - String that represents NULL.HEADER
(boolean) - Include header line when FORMAT csv.QUOTE
(char) - Quoting character for csv (default ").ESCAPE
(char) - Escape character for csv (default ").ENCODING
(name) - Character set of the file.\copy (psql), INSERT, SELECT, COPY INTO (Snowflake), LOAD DATA INFILE (MySQL), BULK INSERT (SQL Server), UNLOAD (Redshift)
PostgreSQL 6.0 (1997)
You must be a superuser or the table owner when reading or writing server-side files. Regular users can still import/export using the client-side \copy command.
Yes. All CHECK constraints, UNIQUE constraints, foreign keys, and row-level triggers execute as if the rows were inserted normally.
From PostgreSQL 12 onward, add the option ON_ERROR = skip or run COPY in a PL/pgSQL loop catching exceptions. Older versions require loading into a staging table and cleaning errors later.
Disable WAL (UNLOGGED tables), drop indexes and constraints before loading, increase maintenance_work_mem, and use BINARY format when both source and target are PostgreSQL.