ChatGPT解决这个技术问题 Extra ChatGPT

psql - save results of command to a file

I'm using psql's \dt to list all tables in a database and I need to save the results.

What is the syntax to export the results of a psql command to a file?


H
Haili Sun

From psql's help (\?):

\o [FILE] send all query results to file or |pipe

The sequence of commands will look like this:

[wist@scifres ~]$ psql db
Welcome to psql 8.3.6, the PostgreSQL interactive terminal

db=>\o out.txt
db=>\dt

Then any db operation output will be written to out.txt. Enter '\o' to revert the output back to console.

db=>\o

do i call this prior to the \dt, or in combination? please include syntax thanks.
Typing \o again turns it off.
Sadly, the output of \? does not go to the file. :(
for your kind perusual permission denied says try to run psql as administrator
Yes, \o queries-output.txt redirects all the subsequent commands o/p to file named queries-output.txt and typing \o (on psql prompt again) reverts this redirection behavior.
i
intgr

The psql \o command was already described by jhwist.

An alternative approach is using the COPY TO command to write directly to a file on the server. This has the advantage that it's dumped in an easy-to-parse format of your choice -- rather than psql's tabulated format. It's also very easy to import to another table/database using COPY FROM.

NB! This requires superuser privileges and will write to a file on the server.

Example: COPY (SELECT foo, bar FROM baz) TO '/tmp/query.csv' (format csv, delimiter ';')

Creates a CSV file with ';' as the field separator.

As always, see the documentation for details


I agree @helvete, the approach presented here provides more power for the user to configure output in a more customizing way
Y
Yavuz

Use o parameter of pgsql command.

-o, --output=FILENAME send query results to file (or |pipe)

psql -d DatabaseName -U UserName -c "SELECT * FROM TABLE" -o /root/Desktop/file.txt

Thanks, was looking for a version that could be sent from CL.
I needed to add -h localhost and do read PGPASSWORD before hand to avoid password prompts (as I was looping over a list of table names)
J
John Clements

\copy which is a postgres command can work for any user. Don't know if it works for \dt or not, but general syntax is reproduced from the following link Postgres SQL copy syntax

\copy (select * from tempTable limit 100) to 'filenameinquotes' with header delimiter as ','

The above will save the output of the select query in the filename provided as a csv file

EDIT:

For my psql server the following command works this is an older version v8.5

copy (select * from table1) to 'full_path_filename' csv header;

Very handy, thanks. But the 'copy' in '... copy to ...' isn't required - in fact on the recent versions it causes the command to fail.
Tom, I think it was a typo. Edited the post with the one that works on my installation pgsql 8.5ver
Just a quick note to anyone attempting to paste in a multi-line statement after \copy and getting confusing syntax errors, as I just did. You need to continue on the same line as \copy.
Is there a way to turn the \copy off? I found that if I run a statement like in your example, and then I run, for example, select * from users; that it will append the results to the most-recent file I specified instead of outputting to the screen. Thank you.
D
Deepak Mahakale

Use the below query to store the result in a CSV file

\copy (your query) to 'file path' csv header;

Example

\copy (select name,date_order from purchase_order) to '/home/ankit/Desktop/result.csv' cvs header;

Hope this helps you.


Thanks for this. Just a remark: at the end of your example it's csv header
D
Deepak Mahakale

If you got the following error

ufgtoolspg=> COPY (SELECT foo, bar FROM baz) TO '/tmp/query.csv' (format csv, delimiter ';');
ERROR:  must be superuser to COPY to or from a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

you can run it in this way:

psql somepsqllink_or_credentials -c "COPY (SELECT foo, bar FROM baz) TO STDOUT (format csv, delimiter ';')"  > baz.csv

D
Deepak Mahakale
COPY tablename TO '/tmp/output.csv' DELIMITER ',' CSV HEADER;

this command is used to store the entire table as csv


In postgres COPY is better replaced by \COPY to avoid need of db admin. In windows this puts the file in C:\tmp
h
hlovdal

I assume that there exist some internal psql command for this, but you could also run the script command from util-linux-ng package:

DESCRIPTION Script makes a typescript of everything printed on your terminal.


E
Eduardo Lucio

This approach will work with any psql command from the simplest to the most complex without requiring any changes or adjustments to the original command.

NOTE: For Linux servers.

Save the contents of your command to a file

MODEL

read -r -d '' FILE_CONTENT << 'HEREDOC'
[COMMAND_CONTENT]

HEREDOC
echo -n "$FILE_CONTENT" > sqlcmd

EXAMPLE

read -r -d '' FILE_CONTENT << 'HEREDOC'
DO $f$
declare
    curid INT := 0;
    vdata BYTEA;
    badid VARCHAR;
    loc VARCHAR;
begin
FOR badid IN SELECT some_field FROM public.some_base LOOP
    begin
    select 'ctid - '||ctid||'pagenumber - '||(ctid::text::point) [0]::bigint
        into loc
        from public.some_base where some_field = badid;
        SELECT file||' '
        INTO vdata
        FROM public.some_base where some_field = badid;
    exception
        when others then
        raise notice 'Block/PageNumber - % ',loc;
            raise notice 'Corrupted id - % ', badid;
            --return;
    end;
end loop;
end;
$f$;

HEREDOC
echo -n "$FILE_CONTENT" > sqlcmd

Run the command

MODEL

sudo -u postgres psql [some_db] -c "$(cat sqlcmd)" >>sqlop 2>&1

EXAMPLE

sudo -u postgres psql some_db -c "$(cat sqlcmd)" >>sqlop 2>&1

View/track your command output

cat sqlop

Done! Thanks! =D


R
Roman Rhrn Nesterov

Approach for docker

via psql command

 docker exec -i %containerid% psql -U %user% -c '\dt' > tables.txt

or query from sql file

docker exec -i %containerid% psql -U %user% < file.sql > data.txt