PostgreSQL
PostgreSQL's COPY text format is tab-separated — a rendered sheet is already a valid COPY stream, and a COPY out is already a sheet. The two formats were made for each other; they just didn't know it.
Everything here runs against grades.tsvt from tsvsheet.examples (fetch it with curl -fsSO https://raw.githubusercontent.com/tsvsheet/tsvsheet.examples/main/grades.tsvt). Add your usual connection flags to each psql; the exact commands below were verified against postgres:17 — see the container section to reproduce them verbatim.
Load a sheet
\copy ... FROM in text format expects tab-separated rows — exactly what tsv render writes. HEADER (PostgreSQL 15+) skips the column row; on older servers, strip it with tail -n +2 instead:
$ psql -c 'CREATE TABLE grades (student text, math numeric, reading numeric, science numeric, average numeric, result text);' CREATE TABLE $ tsv render grades.tsvt | psql -c '\copy grades FROM pstdin WITH (FORMAT text, HEADER)' \ -c 'SELECT result, count(*) AS n, round(avg(average),1) AS avg FROM grades GROUP BY result;' COPY 4 result | n | avg --------+---+------ Fail | 1 | 61.7 Pass | 3 | 83.0 (2 rows)
The Average and Result columns were =formulas in the source sheet; the database receives their computed values.
Query back out as a sheet
The symmetry runs both ways: \copy ... TO in text format emits a tab-separated grid, header included. Append a =formula row and the query result is a living sheet:
$ { psql -c '\copy (SELECT student AS "Student", average AS "Average" FROM grades ORDER BY average DESC) TO pstdout WITH (FORMAT text, HEADER)'
printf 'Class average\t=round(avg(B2:B5), 1)\n'; } | tsv render -
Student Average
Carol 91.3
Alice 84.3
Bob 73.3
Dave 61.7
Class average 77.6For ad-hoc queries outside \copy, psql -A -F $'\t' -P footer=off produces the same header-plus-rows grid.
No postgres handy?
A throwaway container makes the whole recipe reproducible from nothing — this is verbatim what verified this page:
$ docker run --rm -d --name tsvt-pg -e POSTGRES_PASSWORD=pg postgres:17 $ docker exec tsvt-pg pg_isready -U postgres $ tsv render grades.tsvt | docker exec -i tsvt-pg psql -U postgres \ -c 'CREATE TABLE grades (student text, math numeric, reading numeric, science numeric, average numeric, result text);' \ -c '\copy grades FROM pstdin WITH (FORMAT text, HEADER)' \ -c 'SELECT result, count(*) AS n, round(avg(average),1) AS avg FROM grades GROUP BY result;' $ docker stop tsvt-pg # the --rm container and its data vanish