How to pass CLI options to heroku pg:psql? - heroku

Given heroku pg:psql works, connects to database
And $SQL is a valid SQL query
When I run heroku pg:psql -c $SQL
Then I expect to see the results of the query
And I expect heroku to exit with a status code of 0
Instead, the -c option is ignored, $SQL is not executed, and an interactive prompt is shown.

Looks like a bug, sorry about that :-/
I've reported it.
It appears that pg:extras might be the culprit, and if you didn't have that, it may work. See here
Try
heroku plugins:uninstall heroku-pg-extras
There's a work around - pipe the command in:
<<< "select count(*) from features;" | heroku pg:psql -a appname -c -

Related

Cannot get psql command to run in bash script

I'm a bit of a novice at bash scripting, so bear with me. I'm trying to write a script to execute a sql file using psql. From my terminal, it works fine:
psql -f /path/to/file.sql "$URI"
However, in my script I have something like this:
dbURI="postgres://some.connection.string"
psql -f /path/to/file.sql $dbURI
But I keep getting output like this:
psql: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
I cannot seem to get this to work at all. I've tried wrapping the variable in quotes, using $(command), etc, with no luck.
Try using the below in your script to disable globbing
psql -f /path/to/file.sql "$dbURI"
I have just had the same problem, with the exact same error message. The problem was that Postgresql takes a few seconds to start. So, if it is the case that you start postgresql and use a psql command in the same script, chances are that postgre has not yet started when you call it.
The solution was to include:
sleep 5
before the psql command. In your case, this would be:
sleep 5
psql -f /path/to/file.sql "$URI"
This gives some time for postgre to start before you use it.
I see the topic is 2 years old, but in case anyone else faces the same problem.

How can a PostgreSQL database cease to exist in between two consecutive shell commands?

I am trying to create a PostgreSQL database accounts_db in CI (GitLab CI, if it's relevant), but only if that database does not exist yet. Since native Postgres doesn't support that, I currently solve it by running a SELECT on pg_database using psql, and only when that does not return results, I use psql again to run a CREATE DATABASE:
psql -tc "SELECT 1 FROM pg_database WHERE datname = 'accounts_db';" | grep -q 1 || psql -c "CREATE DATABASE accounts_db;"
This works most of the time: accounts_db already exists, so grep exits successfully and the CREATE DATABASE is not executed.
Most of the time is not all the time, though. For some reason, it sometimes ends up in the second part of the ||, only to error out because the database already exists:
$ psql -tc "SELECT 1 FROM pg_database WHERE datname = 'accounts_db';" | grep -q 1 || psql -c "CREATE DATABASE accounts_db;"
ERROR: database "accounts_db" already exists
How is this possible?
BTW: You don't need grep; you can use psql's exit code,just attempt connecting to the new database:
(there are more reasons for psql to exit with non zero exit value; but in that case the second psql will also fail)
#!/bin/sh
THE_NAME="omg_wtf"
psql -U postgres ${THE_NAME} -tc "select 'yes';" || psql -U postgres postgres -tc "CREATE DATABASE ${THE_NAME} ;"
#Eof
But even simpler: just attempt to create the database, and bail out of the script if that fails:
#!/bin/sh
THE_NAME="omg_wtf"
psql -U postgres postgres -tc "CREATE DATABASE ${THE_NAME} ;"|| exit 1
# you wont get here if the above exited
echo "Created ${THE_NAME}"
#Eof
Any chance you've obfuscated the real db name, and the real one sometimes contains mixed case?
Because
SELECT 1 FROM pg_database WHERE datname = 'MyDB'
will match a database named MyDB but not one named mydb. However, if you create the database, you'll get a case-folded name; e.g.
CREATE DATABASE MyDB;
creates a db named mydb. So in this case, your test for existence would report that there's no db named MyDB then you'd go to create it, try to create mydb and fail if it already existed.
The fix is to use identifier quoting:
CREATE DATABASE "MyDB";
to preserve case there. Or alternately, case-fold your query of pg_database to lower case:
SELECT 1 FROM pg_database WHERE datname = lower('MyDB')
... assuming you know you'll only ever attempt to then create it in lower-case.
(It gets even more exciting if the user decides to supply identifier-quoted input to your script...)

Unable to run psql command from within a BASH script

I have run into a problem with the psql command in my BASH script as I am trying to login to my local postgres database and submit a query. I am using the command in the following way:
psql -U postgres -d rebasoft_appauditor -c "SELECT * FROM katan_scripts"
However, I get the following error message.
psql: FATAL: Ident authentication failed for user "postgres"
This runs perfectly fine from the command line after I appended the following changes to /var/lib/pgsql/data/pg_hba.conf:
local all all trust
host all all 127.0.0.1/32 trust
Also, could this please be verified for correctness?
I find it rather strange that database authentication works fine on the command line but in a script it fails. Could anyone please help with this?
Note: I am using MAC OSX
It might possibly depend on your bash script.
Watch for the asterisk (*) not be replaced with the file names in your current directory. And possibly a semicolon or \g might help to actually send the SQL statement to the database server.

PostgreSQL export result as CSV from remote server

I have read all other solutions and none adapts to my needs, I do not use Java, I do not have super user rights and I do not have API's installed in my server.
I have select rights on a remote PostgreSQL server and I want to run a query in it remotely and export its results into a .csv file in my local server.
Once I manage to establish the connection to the server I first have to define the DB, then the schema and then the table, fact that makes the following lines of code not work:
\copy schema.products TO '/home/localfolder/products.csv' CSV DELIMITER ','
copy (Select * From schema.products) To '/home/localfolder/products.csv' With CSV;
I have also tried the following bash command:
psql -d DB -c "select * from schema.products;" > /home/localfolder/products.csv
and logging it with the following result:
-bash: home/localfolder/products.csv: No such file or directory
I would really appreciate if someone can show a light on this.
Have you tried this? I do not have psql right now to test it.
echo “COPY (SELECT * from schema.products) TO STDOUT with CSV HEADER” | psql -o '/home/localfolder/products.csv'
Details:
-o filename Put all output into file filename. The path must be writable by the client.
echo builtin + piping (|) pass command to psql
Aftr a while a good colleague deviced this solution which worked perfectly for my needs, hope this can help someone.
'ssh -l user [remote host] -p [port] \'psql -c "copy (select * from schema.table_name') to STDOUT csv header" -d DB\' > /home/localfolder/products.csv'
Very similar to idobr's answer.
From http://www.postgresql.org/docs/current/static/sql-copy.html:
Files named in a COPY command are read or written directly by the server, not by the client application.
So, you'll always want to use psql's \copy meta command.
The following should do the trick:
\copy (SELECT * FROM schema.products) to 'products.csv' with csv
If the above doesn't work, we'll need an error/warning message to work with.
You mentioned that the server is remote, however you are connecting to a localhost. Add the -h [server here] or set the ENV variable
export PGHOST='[server here]'
The database name should be the last argument, and not with -d.
And finally that command should have not failed, my guess is that that directory does not exist. Either create it or try writing to tmp.
I would ask you to try the following command:
psql -h [server here] -c "copy (select * from schema.products) to STDOUT csv header" DB > /tmp/products.csv

heroku pg: pull not fetching tables from heroku database

I'm trying to pull a heroku database to my local Windows computer by using heroku bash command
heroku pg:pull HEROKU_POSTGRESQL_COLOR mydatabase --app appname,
when I running above command I get the following error:
'env' is not recognized as an internal or external command, operable program or batch file.!
But local database 'mydatabase' is created, but without any tables.
My heroku app's database has a table in it, but it is not getting pulled to my local database.
Help me to solve it.
a couple of things:
1.When there is an error such as "'env' is not recognized as an internal or external command, operable program or batch file" it means that the system is trying to execute a command named env. This has nothing to do at all with setting up your environment variables.
Env is not a command in windows, but in unix. I understand that you have a windows machine though. What you can do is run "git bash". (You could get it by itself but it comes with Heroku's CLI).
This gives you a unix-like environment where the "env" command is supported, and then you can run the actual heroku pg:pull command.
2.If that still doesn't work, there is a workaround which works,without installing anything extra. Actually this is based on a ticket which I submitted to Heroku so I'm just going to quote their response:
"The pg:push command is just a wrapper around pg_dump and pg_restore commands. Due to the bug you encountered, it sounds like we should go ahead and do things manually. Run these using cmd.exe (The Command Prompt application you first reported the bug). First grab the connection string from your heroku application config vars.
heroku config:get DATABASE_URL
Then you want to pick out the username / hostname / databasename parts from the connection string, ie: postgres:// username : password # hostname : port / databasename. Use those variables in the following command and paste in the password when prompted for one. This will dump the contents of your heroku database for a local file.
pg_dump --verbose -F c -Z 0 -U username -h hostname -p port databasename > heroku.dump
Next you will load this file into your local database. One thing that the CLI does before running this command is to check and make sure the target database is empty, because running this against a database with real data is something you want to avoid so be careful with pg_restore. When running this manually you run the risk of mangling your data without the CLI check, so you may want to manually verify that the target database is empty first.
pg_restore --verbose --no-acl --no-owner -h localhost -p 5432 -d mydb2 < heroku.dump
I am sorry this is not a better experience, I hope this will help you make progress. We are in the process of rewriting our pg commands so that they work better on all platforms including windows, but there is no solid timeline for when this will be completed."
For taking backup like dump file in heroku firstly you need the backups addon, installing..
$heroku addons:add pgbackups
Then running below command will give you dump file in the name of latest
$ heroku pgbackups:capture
$ curl -o latest.dump `heroku pgbackups:url`
or
wget "`heroku pgbackups:url --app app-name`" -O backup.dump
Edited:(After chatting with user,)
Problem: 'env' is not recognized as an internal or external command, operable program or batch file.!
I suspected that one of the PATH variable to particular program is messed up. You can double click and check that in WINDOWS\system32 folder.
Ok so How to edit it:
My Computer > Advanced > Environment Variables
Then choose PATH and click edit button

Resources