Export Table to CSV File

Learn how to export a PostgreSQL table or query result to a CSV file using the COPY statement and the psql \copy command, including partial column exports.

4 min read · Last updated: March 2026 · Back to overview

Quick Answer

Use the PostgreSQL COPY statement to export a table to CSV on the server: COPY table_name TO '/path/to/file.csv' DELIMITER ',' CSV HEADER. To save the file to your local machine, use the psql \copy command, which transfers data through the client connection without requiring superuser privileges.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

PostgreSQL offers two commands for exporting table data to CSV: the server-side COPY ... TO statement and the client-side psql \copy command. The server-side command writes the file directly on the database host and requires superuser access; the client-side command streams data to a file on your local machine using ordinary user privileges.

Exporting with the COPY statement

Assume the persons table contains the following data:

SELECT * FROM persons;
 id | first_name | last_name |    dob     |              email
----+------------+-----------+------------+---------------------------------
  1 | John       | Doe       | 1995-01-05 | [email protected]
  2 | Jane       | Doe       | 1995-02-05 | [email protected]

Export the entire table to a CSV file with a header row:

COPY persons
TO '/var/lib/postgresql/persons_db.csv'
DELIMITER ','
CSV HEADER;
COPY 2

Export only selected columns:

COPY persons (first_name, last_name, email)
TO '/var/lib/postgresql/persons_partial_db.csv'
DELIMITER ','
CSV HEADER;

Export just the email column without a header:

COPY persons (email)
TO '/var/lib/postgresql/persons_email_db.csv'
DELIMITER ','
CSV;

The output file must be writable by the OS user that runs the PostgreSQL server process. The path is resolved on the server, not the client machine.

Exporting a query result with copy

When you need the file on your local machine or lack superuser rights, use the psql \copy meta-command. It accepts an arbitrary SELECT query as the source:

copy (SELECT * FROM persons) TO '/Users/you/persons_client.csv' WITH CSV

You can filter and shape the export with any SELECT syntax:

copy (
  SELECT first_name, last_name, email
  FROM persons
  ORDER BY last_name, first_name
) TO '/Users/you/persons_sorted.csv' WITH (FORMAT csv, HEADER true)

Production tips for exporting CSV data

  • Wrap a subquery in COPY (...) TO to filter, join, or transform data before writing — you are not limited to exporting a whole table.
  • Always include HEADER when the CSV will be consumed by tools that expect column names in the first row.
  • Add an ORDER BY inside the subquery to produce a deterministic file, which helps with diffing exports across runs.
  • For large exports, run COPY outside of an explicit transaction to avoid holding a snapshot lock for the duration of the write.
  • Use \copy in scripts and CI pipelines rather than COPY to avoid hard dependencies on server-side file paths.

Continue in Import / Export: Back to tutorial overview.

Related in this section: Import CSV File into Table

Frequently Asked Questions

What is the difference between COPY TO and \copy in PostgreSQL?

COPY TO is a server-side SQL command that writes the file on the PostgreSQL host machine and requires superuser privileges. \copy is a psql client-side command that streams data to a file on your local machine and works with ordinary user permissions.

How do I export only certain columns to a CSV file?

List the columns in parentheses after the table name: COPY persons (first_name, last_name, email) TO '/path/file.csv' CSV HEADER.

Can I export the result of a SELECT query to a CSV file?

Yes. Wrap your query in parentheses after COPY: COPY (SELECT * FROM persons WHERE dob > '2000-01-01') TO '/path/file.csv' CSV HEADER. The psql \copy command also accepts a subquery.

How do I export to a tab-separated file instead of CSV?

Use DELIMITER E'\t' and omit the CSV keyword, or use the TEXT format: COPY persons TO '/path/file.tsv' DELIMITER E'\t'.

Does the COPY TO command overwrite an existing file?

Yes. If the destination file already exists, COPY TO overwrites it without warning. Make sure the path is correct before running the command.