PostgreSQL: LISTEN and COPY export
The PostgreSQL driver can follow a LISTEN channel and export results
with the server’s own COPY. Greenplum has both;
CockroachDB has the export only; Amazon Redshift
has neither.
Following a channel
PostgreSQL has no change streams, so a live tail follows a LISTEN channel. Every NOTIFY on
that channel arrives as an event with the op notify, the channel name and the payload.
tobira watch app orders_changed
tobira watch app orders_changed --format table --max 10
In the terminal UI, :watch orders_changed opens a live tail tab. See
also tobira watch.
- tobira starts listening before the command returns, so a
NOTIFYsent right after is not missed. - The channel name keeps its case and punctuation. A name longer than 63 bytes is refused, because the server would cut it.
- Watching never writes, so it works on read-only connections.
- If the server connection is lost, the watch ends with that error.
- A watch holds one connection of its own for as long as it runs.
Native csv export
tobira query --output file.csv with no --limit lets the server write the csv with
COPY (<query>) TO STDOUT. The values are then PostgreSQL’s own text (booleans as t and f),
and the file is streamed in constant memory. See Export for the general rules.
tobira query app "select * from orders" --output orders.csv
The native export only takes one SELECT, WITH, VALUES or TABLE statement, without bind
parameters or a row limit (put LIMIT in the query). It always runs in a read-only transaction
that is rolled back, on writable connections too. When it refuses a query, tobira writes the
file with its own csv writer instead:
- on a writable connection, a query that writes (
nextval(), a data-modifyingWITH) falls back to tobira’s csv; - on a read-only connection, such a query stays refused.
Set --limit to always use tobira’s csv.
The export also refuses everything the read-only guard
refuses (COPY, DO, server-file functions), on every connection, and it checks that the query
text cannot break out of the COPY ( ... ) around it.