psql - write a query and the query's output to a file - postgresql

In postgresql 9.3.1, when interactively developing a query using the psql command, the end result is sometimes to write the query results to a file:
boron.production=> \o /tmp/output
boron.production=> select 1;
boron.production=> \o
boron.production=> \q
$ cat /tmp/output
?column?
----------
1
(1 row)
This works fine. But how can I get the query itself to be written to the file along with the query results?
I've tried giving psql the --echo-queries switch:
-e, --echo-queries
Copy all SQL commands sent to the server to standard output as well.
This is equivalent to setting the variable ECHO to queries.
But this always echoes to stdout, not to the file I gave with the \o command.
I've tried the --echo-all switch as well, but it does not appear to echo interactive input.
Using command editing, I can repeat the query with \qecho in front of it. That works, but is tedious.
Is there any way to direct an interactive psql session to write both the query and the query output to a file?

You can try redirecting the stdout to a file directly from your shell (Win or Linux should work)
psql -U postgres -c "select 1 as result" -e nomedb >> hello.txt
This has the drawback of not letting you see the output interactively. If that's a problem, you can either tail the output file in a separate terminal, or, if in *nix, use the tee utility:
psql -U postgres -c "select 1 as result" -e nomedb | tee hello.txt
Hope this helps!
Luca

I know this is an old question, but at least in 9.3 and current versions this is possible using Query Buffer meta-commands shown in the documentation or \? from the psql console: https://www.postgresql.org/docs/9.3/static/app-psql.html
\w or \write filename
\w or \write |command
Outputs the current query buffer to the file filename or pipes it to the shell command command.

Please try this format as I got the output from the same:
psql -h $host -p $port -q -U $user -d $Dbname -c "SELECT \"Employee-id\",\"Employee-name\" FROM Employee_table" >> Employee_Date.csv
I need the output in a CSV file.

Related

How to pass sql file in "\copy" psql command line

I am trying to find a way to pass a file to psql while using '\copy'. There is a question posted here use sql file in "\copy" psql command line asking a similar thing, but the accepted solution doesn't actually pass a file to psql, it passes the contents of the file, so this cannot be done when the contents of the sql file exceeds the maximum allowed length of the psql command.
e.g. something like this psql -c data_base "\copy \file_path <file.sql> To './test.csv' With CSV"
Using copy rather than \copy, you can do it like this:
(echo "copy ("; cat file.sql ; echo ") to STDOUT with CSV")| psql -X > ./test.csv

How capture "ANALYZE VERBOSE tablename" output into logfile

I would like to capture output of "ANALYZE VERBOSE TableName" into output file when executed from shell script.
Want to capture this:
INFO: analyzing "tablename" INFO: "tablename": scanned 1 of 1 pages,
containing 7 live rows and 2 dead rows; 7 rows in sample, 7 estimated
total rows
Using this command
psql -h $DB_HOST_NAME -U $DB_USER $DB_NAME -f query.txt --echo-errors --echo-queries >> output.log
But its only capturing text "ANALYZE" not capturing entire text.
Please suggest how to print entire text into output file.
The output you are trying to capture is directed through stderr, so you need to capture/redirect that output at the shell level. This can be tempermental based on your versions of your OS / Shell. On OSX with 3.2.57, you would need to use:
psql -h $DB_HOST_NAME -U $DB_USER $DB_NAME -f query.txt --echo-queries >> output.log 2>&1 ;
If that doesn't work, try looking up the specifics for whatever combination of OS/shell you are using.

Postgres from unix shell out put not appear in Log

I am writing a batch job for Postgres for first time. I have return ".sh" file, which has a command with out any out put in the log or console.
Code
export PGPASSWORD=<password>
psql -h <host> -p <port> -U <user> -d <database> --file cleardata.sql > log\cleardata.log 2>&1
What I did at cammond line
su postgres
and run ./cleardatasetup.sh
Nothing is happening.
Please note : When I try psql command in Unix command line, I am getting message as some SQL exception which is valid.
Can any one please help me in this regard.
You probably wanted to create log/cleardata.log but you have a backslash where you need a slash. You will find that the result is a file named log\cleardata.log instead.
The backslash is just a regular character in the file's name, but it's special to the shell, so you'll need to quote or escape it to (unambiguously) manipulate it from the shell;
ls -l log\\cleardata.log # escaped
mv 'log\cleardata.log' log/cleardata.log # quoted

Store PostgreSQL query result to Shell or PostgreSQL variable

For instance, I have a table stores value:
select * from myvalue;
val
-------
12345
(1 row)
How can I save this 12345 into a variable in postgresql or shell script?
Here's what I tried in my shell script:
var=$(psql -h host -U user -d db <<SQLSTMT
SELECT * FROM myvalue;
SQLSTMT)
but echo $var gives me:
val ------- 12345 (1 row)
I've also tried
\set var (select * from myvalue)
in psql and when I type \set it lists:
var = '(select*frommyvalue)'
No, no, no! Use "raw data" switch from psql, like "-t" or "\t" and pipe the query to psql instead of parsing ascii-table, come on :-)
echo 'select * from myvalue;' | psql -t -h host -U user -d db
If you really need parse psql output, you could also use -H switch ( turns on HTML output ), and parse it with some perl module for parsing html tables, I used that once or twice.. Also, you may want to use a pgpass file and ~/.psqlrc for some defaults, like default DB to connect, when not specified.
psql has a -c/--command= option to accept SQL from the command line, and -t/--tuples-only option to control output formatting.
$ psql -c 'select 1+1'
?column?
----------
2
(1 row)
$ psql -t -c 'select 1+1'
2
$ VALUE=`psql -t -c 'select 1+1'`
$ echo $VALUE
2
var=`psql -Atc "select 1;"`
echo $var
1
In this answer I explain one way to do it, using a co-process to communicate back-and-forth with psql. That's overkill if all you need is to run a query and get a single result, but might be good to know if you're shell scripting with psql.
You can filter the result you get with your psql command:
var=$(psql -h host -U user -d db <<SQLSTMT
SELECT * FROM myvalue;
SQLSTMT)
var=$(cut -d' ' -f3 <<<$var)
None of these worked for me, but this did:
median_avm=psql "host=${dps1000} port=#### dbname=### user=${reduser} password=${redpass}" -c "SELECT AVG(column) FROM db.table;" -t
using a source file with ${dps1000}, ${reduser}, ${redpass} defined and manually entering port and dbname

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?
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
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 or pg_write_server_files 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
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
\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;
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.
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
COPY tablename TO '/tmp/output.csv' DELIMITER ',' CSV HEADER;
this command is used to store the entire table as csv
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.
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
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