Check if database exists in PostgreSQL using shell - postgresql

I was wondering if anyone would be able to tell me about whether it is possible to use shell to check if a PostgreSQL database exists?
I am making a shell script and I only want it to create the database if it doesn't already exist but up to now haven't been able to see how to implement it.

Note/Update (2021): While this answer works, philosophically I agree with other comments that the right way to do this is to ask Postgres.
Check whether the other answers that have psql -c or --command in them are a better fit for your use case (e.g. Nicholas Grilly's, Nathan Osman's, bruce's or Pedro's variant
I use the following modification of Arturo's solution:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
What it does
psql -l outputs something like the following:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-----------+----------+------------+------------+-----------------------
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
Using the naive approach means that searching for a database called "List, "Access" or "rows" will succeed. So we pipe this output through a bunch of built-in command line tools to only search in the first column.
The -t flag removes headers and footers:
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
The next bit, cut -d \| -f 1 splits the output by the vertical pipe | character (escaped from the shell with a backslash), and selects field 1. This leaves:
my_db
postgres
template0
template1
grep -w matches whole words, and so won't match if you are searching for temp in this scenario. The -q option suppresses any output written to the screen, so if you want to run this interactively at a command prompt you may with to exclude the -q so something gets displayed immediately.
Note that grep -w matches alphanumeric, digits and the underscore, which is exactly the set of characters allowed in unquoted database names in postgresql (hyphens are not legal in unquoted identifiers). If you are using other characters, grep -w won't work for you.
The exit status of this whole pipeline will be 0 (success) if the database exists or 1 (failure) if it doesn't. Your shell will set the special variable $? to the exit status of the last command. You can also test the status directly in a conditional:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi

The following shell code seems to work for me:
if [ "$( psql -XtAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ]
then
echo "Database already exists"
else
echo "Database does not exist"
fi
Quick help about the psql flags given above:
General options:
-c, --command=COMMAND run only single command (SQL or internal) and exit
-X, --no-psqlrc do not read startup file (~/.psqlrc)
Output format options:
-A, --no-align unaligned table output mode
-t, --tuples-only print rows only

I'm new to postgresql, but the following command is what I used to check if a database exists
if psql ${DB_NAME} -c '\q' 2>&1; then
echo "database ${DB_NAME} exists"
fi

postgres#desktop:~$ psql -l | grep <exact_dbname> | wc -l
This will return 1 if the database specified exists or 0 otherwise.
Also, if you try to create a database that already exists, postgresql will return an error message like this:
postgres#desktop:~$ createdb template1
createdb: database creation failed: ERROR: database "template1" already exists

You can create a database, if it doesn't already exist, using this method:
if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi

I'm combining the other answers to a succinct and POSIX compatible form:
psql -lqtA | grep -q "^$DB_NAME|"
A return of true (0) means it exists.
If you suspect your database name might have a non-standard character such as $, you need a slightly longer approach:
psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
The -t and -A options make sure the output is raw and not "tabular" or whitespace-padded output. Columns are separated by the pipe character |, so either the cut or the grep has to recognize this. The first column contains the database name.
EDIT: grep with -x to prevent partial name matches.

#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#

For completeness, another version using regex rather than string cutting:
psql -l | grep '^ exact_dbname\b'
So for instance:
if psql -l | grep '^ mydatabase\b' > /dev/null ; then
echo "Database exists already."
exit
fi

The other solutions (which are fantastic) miss the fact that psql can wait a minute or more before timing out if it can't connect to a host. So, I like this solution, which sets the timeout to 3 seconds:
PGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""
This is for connecting to a development database on the official postgres Alpine Docker image.
Separately, if you're using Rails and want to setup a database if it doesn't already exist (as when launching a Docker container), this works well, as migrations are idempotent:
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup

kibibu's accepted answer is flawed in that grep -w will match any name containing the specified pattern as a word component.
i.e. If you look for "foo" then "foo-backup" is a match.
Otheus's answer provides some good improvements, and the short version will work correctly for most cases, but the longer of the two variants offered exhibits a similar problem with matching substrings.
To resolve this issue, we can use the POSIX -x argument to match only entire lines of the text.
Building on Otheus's answer, the new version looks like this:
psql -U "$USER" -lqtA | cut -d\| -f1 | grep -qFx "$DBNAME"
That all said, I'm inclined to say that Nicolas Grilly's answer -- where you actually ask postgres about the specific database -- is the best approach of all.

psql -l|awk '{print $1}'|grep -w <database>
shorter version

I'm still pretty inexperienced with shell programming, so if this is really wrong for some reason, vote me down, but don't be too alarmed.
Building from kibibu's answer:
# If resulting string is not zero-length (not empty) then...
if [[ ! -z `psql -lqt | cut -d \| -f 1 | grep -w $DB_NAME` ]]; then
echo "Database $DB_NAME exists."
else
echo "No existing databases are named $DB_NAME."
fi

This command will return the number of databases that are called DATABASE_NAME: psql -At -U postgres -c "select count(*) from pg_databases where datname = 'DATABASE_NAME';
So
if [ "$(psql -At -U postgres -c "select count(*) from pg_databases where datname = 'DATABASE_NAME`;")" -eq 0 ] ; then
# This runs if the DB doesn't exist.
fi

In one line:
PGPASSWORD=mypassword psql -U postgres#hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0
This will return 1 if db exists 0 if not
or more readable:
if [ "$(PGPASSWORD=mypassword psql -U postgres#hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0 )" = '1' ]
then
echo "Database already exists"
else
echo "Database does not exist"
fi

Trigger divide by zero if it doesn't exist then check return code like this:
sql="SELECT 1/count(*) FROM pg_database WHERE datname='db_name'";
error=$(psql -h host -U user -c "$sql" postgres);
if $error
then
echo "doesn't exist";
else
echo "exists";
fi

Related

Psql output csv file formatting

Trying to make batch file that will get query from script file and put results into csv.
Batch file code:
psql -h host -d test -U test -p 5432 -a -q -f C:\Users\test\Documents\my_query.sql TO STDOUT WITH CSV HEADER DELIMITER ';' > C:\Users\test\Documents\res.csv
In result file I'm getting result like this:
select *
from public.test
limit 3
id | name | count_01
----------+------------+---------------+
11021555 | a | 1 |
39534568 | b | 2 |
11695210 | c | 3 |
(3 rows)
How to get only script results without rows count and symbols like '|' or '+' and using ';' delimetres as in the usual csv file?
Working script:
psql -h host -d test -U test -p 5432 -q --quiet --no-align --field-separator=';' --file=C:\Users\test\Documents\my_query.sql --output=C:\Users\test\Documents\res.csv
From PostgreSQL v12 on, you can use the CSV output format of psql:
psql --quiet --csv --file=my_query.sql --output=res.csv
--quiet suppresses the psql welcome message.
Should work with
psql -h host -d dbname -U user -p port -a -q -f my_query.sql -o res.csv --record-separator=',' --csv

Postgresql database size is lower after restore

I just made a simple bash script to backup a postgresql database from remote server and restore it to the same server with prefix _bak. This script looks like:
export FILENAME="/var/pg-backups/$4-$(date +%s).bak"
echo "$(date) Creating dump with args - $1 $2 $3 $4. Filename = $FILENAME"
pg_dump -h $1 -p $2 -U $3 -b -F d -j 4 -v -f "$FILENAME" $4
echo "$(date) Re-create _bak database"
psql -h $1 -p $2 -U $3 -d $4 -c "drop database if exists $4_bak;"
psql -h $1 -p $2 -U $3 -d $4 -c "create database $4_bak;"
echo "$(date) Restoring hot copy with _bak postfix"
pg_restore -h $1 -p $2 -U $3 -d "$4_bak" -w -v "$FILENAME"
echo "$(date) Done"
It works well, but there's some strange thing with _bak database, which was restored - it weights lower than original!! Here's the output of pg_database_size for original (backuped) database and its restored copy:
postgres=# select pg_database_size('somedb');
pg_database_size
------------------
548152175
postgres=# select pg_database_size('somedb_bak');
pg_database_size
------------------
511648623
(1 строка)
Also, I took one table as an example to check relation size difference, with such query:
select pg_relation_size('resources.attachment', 'main') as main,
pg_relation_size('resources.attachment', 'fsm') as fsm,
pg_relation_size('resources.attachment', 'vm') as vm,
pg_relation_size('resources.attachment', 'init') as init,
pg_table_size('resources.attachment'), pg_indexes_size('resources.attachment') as indexes,
pg_total_relation_size('resources.attachment') as total;
and here's what I got for original database:
main | fsm | vm | init | pg_table_size | indexes | total
-------+-------+------+------+---------------+---------+-----------
65536 | 24576 | 8192 | 0 | 109158400 | 32768 | 109191168
and backuped version:
main | fsm | vm | init | pg_table_size | indexes | total
-------+-------+----+------+---------------+---------+-----------
65536 | 24576 | 0 | 0 | 100302848 | 32768 | 100335616
So only pg_table_size and VM differs... records count is the same btw in original and backuped table.
Can someone please try to explain the size difference between original and restored database?
Postgresql verison:
PostgreSQL 12.7 (Debian 12.7-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
P.S.
i've also tried -F c without parallelism - same result

PostgreSQL's `initdb` fails with "invalid locale settings; check LANG and LC_* environment variables"

Already found a solution for this (see answer below), but I am not sure that it is the appropriate one; plus this may help someone else too.
Tried to set up PostgreSQL by following the documentation (18.2 Creating a Database Cluster), but got the following error on Ubuntu 18.04 (kernel: 4.15.0-22-generic):
$ initdb -D /usr/local/pgsql/data
(...)
initdb: invalid locale settings; check LANG and LC_* environment variables
Found a couple answers on Stackoverflow (1, 2) that were relevant, but these did not resolve the issue and the one on Serverfault suggested to restart the service, but PostgreSQL wasn't even running.
Tried passing the locale explicitly in every variation that I found on the system, but these failed too,
3617 2018/06/07-08:36 initdb -D ~/Downloads/ --locale=en_US.utf8
3618 2018/06/07-08:36 initdb -D ~/Downloads/ --locale=en_US.UTF8
3621 2018/06/07-08:37 initdb -D ~/Downloads/ --locale=en_US.UTF-8
3622 2018/06/07-08:37 initdb -D ~/Downloads/ --locale="en_US.UTF-8"
3623 2018/06/07-08:37 initdb -D ~/Downloads/ --locale="en_US.utf8"
3645 2018/06/07-09:24 initdb -D ~/Downloads/ --locale="en_US.utf8"
with
initdb: invalid locale name <the_option_value_above>
There was an Arch Linux forum discussion about this, but there were no solution.
2018/06/07 1214 UPDATE
I linked answers above, but perhaps wasn't explicit enough: I did look at locale -a and locale (not listing the former's output because I installed ALL of them in my attempts below):
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
What have been tried, but did not work (and terminal has been restarted for every iteration):
https://askubuntu.com/questions/454260/how-to-solve-locale-problem
Selected and configured ALL locales.
$ sudo locale-gen en_US.UTF-8
$ sudo dpkg-reconfigure locales.
https://github.com/singularityware/singularity/issues/11
neither
echo "LC_ALL=en_US.UTF-8" >> /etc/environment
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
locale-gen en_US.UTF-8
nor
sudo apt clean
sudo apt update
sudo apt upgrade
sudo apt-get install -y locales language-pack-fi language-pack-en
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
sudo locale-gen en_US.UTF-8
sudo dpkg-reconfigure locales
https://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue/229512#229512
https://askubuntu.com/questions/114759/warning-setlocale-lc-all-cannot-change-locale
(Basically variations of the github link above, tried it anyway.)
TODO:
https://unix.stackexchange.com/questions/294845/bash-warning-setlocale-lc-all-cannot-change-locale-en-us-utf-8
From this thread:
initdb -D <your_data_location> --no-locale --encoding=UTF8
where
--locale=LOCALE set default locale for new databases
--no-locale equivalent to --locale=C
There are caveats (see warning below), but an all-utf8 database can be created using template0 (see 21.3. Template Databases).
From the client (psql):
postgres=# create database test LC_COLLATE "en_US.UTF-8" LC_CTYPE "en_US.UTF-8" template template0;
Or via createdb:
createdb --lc-collate="en_US.UTF-8" --lc-ctype="en_US.UTF-8" --template="template0" test2
Check:
$ psql
psql (10.3)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
test | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
test2 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
WARNING: This is probably not the correct solution and the workaround above is just that, a workaround.
Note the "Collate" and "Ctype" fields below in a database created with the above solution and this may cause issues, because "The results of comparisons between strings depends on LC_CTYPE. In practice, the most visible effect is the sort order." (see DBA StackExchange thread). This is also confirmed on the PostgreSQL mailing list (see this thread about this issue on a database in production). Probably the easiest way to solve this would be re-initializing/recreating the database.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+---------+-------+-----------------------
postgres | postgres | UTF8 | C | C |
template0 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | C | C | =c/postgres +
| | | | | postgres=CTc/postgres
(3 rows)
Although the question does not mention Nix, the original poster linked to this issue from the Nix discourse site so I believe this is a Nix-related issue.
I ran into this issue when running under Nix shell and found the solution here after much searching. I just had to add glibcLocales to my environment. I.e. either run nix-shell -p glibcLocales or add glibcLocales to buildInputs.
You can get a listing of the locales available in Linux with
locale -a
Use one of these.
You have to choose a locale that matches your encoding, for example
initdb -E UTF8 --locale=en_US.utf8
or
initdb -E LATIN9 --locale=et_EE.iso885915
As far as I know, you can install additional locales with
sudo apt-get install language-pack-XX
Check if the locale is enabled in /etc/locale.gen. On my fresh install of Arch Linux ARM the following line was commented out:
en_US.UTF-8 UTF-8
Run locale-gen without any arguments. It will list all the uncommented locales as it generates them.
Optional: edit /etc/locale.conf to set the system locale:
echo "LANG=en_US.UTF-8" > /etc/locale.conf
Restart the system to make all services pick up the new setting.
Run your initdb command.
for me it was an issue when I tried to upgrade postgres from 9.6 to 15.
locale should be replaced with local-provider and icu locale, e.g.:
POSTGRES_INITDB_ARGS="--locale=nl_NL --encoding=UTF8"
->
POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=nl_NL --encoding=UTF8

job stalls with (END)

I'm trying to set up two databases on travis but it just stops halfway the before_install stating:
(END)
No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself.
The build has been terminated
eg https://travis-ci.org/B3Partners/brmo/builds/85746119
my yml is the following:
language: java
sudo: false
branches:
only:
- travis-integration
addons:
postgresql: "9.3"
jdk:
# - openjdk6
# - openjdk7
- oraclejdk7
# - oraclejdk8
matrix:
fast_finish: true
cache:
directories:
- $HOME/.m2
before_install:
# STAGING
- psql --version
- psql -U postgres -c 'create database staging'
- psql -U postgres -c 'create database rsgb'
- psql -U postgres --list
# set up RSGB
- psql -U postgres -d rsgb -c 'create extension postgis'
- psql -U postgres -d rsgb -f ./datamodel/generated_scripts/datamodel_postgresql.sql --single-transaction --echo-all
# - psql -f ./datamodel/utility_scripts/111a_update_gemeente_geom.sql -U postgres -d rsgb --single-transaction
# - psql -f ./datamodel/utility_scripts/113a_update_wijk_geom.sql -U postgres -d rsgb --single-transaction
install:
# install all dependencies + artifacts without any testing
- mvn install -Dmaven.test.skip=true -B -V -fae -q
before_script:
# dit dient na afloop van de 'install' gedaan te worden omdat de staging DB sql gegenereerd wordt door Hibernate
- psql -U postgres -d staging -f ./brmo-persistence/target/ddlscripts/create-brmo-persistence-postgresql.sql --single-transaction
- psql -U postgres -d staging -f ./brmo-persistence/db/01_create_indexes.sql
- psql -U postgres -d staging -f ./brmo-persistence/db/02_insert_default_user.sql
- psql -U postgres -d staging -f ./brmo-persistence/db/03_update_status_enum_value.sql
# run tests
script:
# run unit tests
- mvn -e test -B
# run integration tests
- mvn -e verify -B
after_success:
after_failure:
after_script:
notifications:
email: false
# on_success: [always|never|change] # default: change
# on_failure: [always|never|change] # default: always
and as you can see in the log it just stalls after a few psql calls.
0.01s$ psql --version
psql (PostgreSQL) 9.3.5
before_install.2
0.02s$ psql -U postgres -c 'create database staging'
CREATE DATABASE
before_install.3
0.22s$ psql -U postgres -c 'create database rsgb'
CREATE DATABASE
before_install.4
1.04s$ psql -U postgres -d rsgb -c 'create extension postgis'
CREATE EXTENSION
$ psql -U postgres --list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
rsgb | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
staging | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
travis | travis | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(6 rows)
(END)
No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself.
The build has been terminated
I just spent about 3 hours troubleshooting this same issue and the problem is pretty simple once you understand why. psql is simply trying to page the output. There are multiple ways to disable the pager, but the solution I went with was to set the PAGER=cat environment variable in .travis.yml like so:
env:
- PGUSER=postgres
PAGER=cat

psql: FATAL: database "<user>" does not exist

I'm using the PostgreSql app for mac (http://postgresapp.com/). I've used it in the past on other machines but it's giving me some trouble when installing on my macbook. I've installed the application and I ran:
psql -h localhost
It returns:
psql: FATAL: database "<user>" does not exist
It seems I can't even run the console to create the database that it's attempting to find. The same thing happens when I just run:
psql
or if I launch psql from the application drop down menu:
Machine stats:
OSX 10.8.4
psql (PostgreSQL) 9.2.4
Any help is appreciated.
I've also attempted to install PostgreSql via homebrew and I'm getting the same issue. I've also read the applications documentation page that states:
When Postgres.app first starts up, it creates the $USER database,
which is the default database for psql when none is specified. The
default user is $USER, with no password.
So it would seem the application is not creating $USER however I've installed->uninstalled-reinstalled several times now so it must be something with my machine.
I found the answer but I'm not sure exactly how it works as the user who answered on this thread -> Getting Postgresql Running In Mac: Database "postgres" does not exist didn't follow up. I used the following command to get psql to open:
psql -d template1
I'll leave this one unanswered until someone can provide an explanation for why this works.
It appears that your package manager failed to create the database named $user for you. The reason that
psql -d template1
works for you is that template1 is a database created by postgres itself, and is present on all installations.
You are apparently able to log in to template1, so you must have some rights assigned to you by the database. Try this at a shell prompt:
createdb
and then see if you can log in again with
psql -h localhost
This will simply create a database for your login user, which I think is what you are looking for. If createdb fails, then you don't have enough rights to make your own database, and you will have to figure out how to fix the homebrew package.
From the terminal, just Run the command on your command prompt window. (Not inside psql).
createdb <user>
And then try to run postgres again.
By default, postgres tries to connect to a database with the same name as your user. To prevent this default behaviour, just specify user and database:
psql -U Username DatabaseName
Login as default user: sudo -i -u postgres
Create new User: createuser --interactive
When prompted for role name, enter linux username, and select Yes to superuser question.
Still logged in as postgres user, create a database: createdb <username_from_step_3>
Confirm error(s) are gone by entering: psql at the command prompt.
Output should show psql (x.x.x) Type "help" for help.
Login using default template1 database:
#psql -d template1
#template1=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+---------+----------+-------------+-------------+---------------------
postgres | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/gogasca +
| | | | | gogasca=CTc/gogasca
template1 | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/gogasca +
| | | | | gogasca=CTc/gogasca
(3 rows)
Create a database with your userId:
template1=# CREATE DATABASE gogasca WITH OWNER gogasca ENCODING 'UTF8';
CREATE DATABASE
Quit and then login again
template1=# \q
gonzo:~ gogasca$ psql -h localhost
psql (9.4.0)
Type "help" for help.
gogasca=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+---------+----------+-------------+-------------+---------------------
gogasca | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/gogasca +
| | | | | gogasca=CTc/gogasca
template1 | gogasca | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/gogasca +
| | | | | gogasca=CTc/gogasca
(4 rows)
I faced the same error when I trying to open postgresql on mac
psql: FATAL: database "user" does not exist
I found this simple command to solve it:
method1
$ createdb --owner=postgres --encoding=utf8 user
and type
psql
Method 2:
psql -d postgres
Post installation of postgres, in my case version is 12.2, I did run the below command createdb.
$ createdb `whoami`
$ psql
psql (12.2)
Type "help" for help.
macuser=#
Step 1:
psql -d template1
now you should be on psql terminal
Step 2:
CREATE DATABASE username;
make sure you use semicolon (;) after the database name;
optional: on psql terminal type \ls or \l to list all the databases;
Step 3:
psql -h localhost
now you should be connected;
Try using-
psql -d postgres
I was also facing the same issue when I ran psql
Had the same problem, a simple psql -d postgres did it (Type the command in the terminal)
This error can also occur if the environment variable PGDATABASE is set to the name of a database that does not exist.
On OSX, I saw the following error while trying to launch psql from the Postgress.app menu:
psql: FATAL: database "otherdb" does not exist
The solution to the error was to remove export PGDATABASE=otherdb from ~/.bash_profile:
Further, if PGUSER is set to something other than your username, the following error will occur:
psql: FATAL: role "note" does not exist
The solution is to remove export PGUSER=notme from ~/.bash_profile.
Not sure if it is already added in the answers, Anatolii Stepaniuk answer was very helpful which is the following.
psql -U Username postgres # when you have no databases yet
As the createdb documentation states:
The first database is always created by the initdb command when the data storage area is initialized... This database is called postgres.
So if certain OS/postgresql distributions do that differently, it is certainly not the default/standard (just verified that initdb on openSUSE 13.1 creates the DB "postgres", but not "<user>"). Long story short, psql -d postgres is expected to be used when using a user other than "postgres".
Obviously the accepted answer, running createdb to create a DB named like the user, works as well, but creates a superfluous DB.
Since this question is the first in search results, I'll put a different solution for a different problem here anyway, in order not to have a duplicate title.
The same error message can come up when running a query file in psql without specifying a database. Since there is no use statement in postgresql, we have to specify the database on the command line, for example:
psql -d db_name -f query_file.sql
First off, it's helpful to create a database named the same as your current use, to prevent the error when you just want to use the default database and create new tables without declaring the name of a db explicitly.
Replace "skynotify" with your username:
psql -d postgres -c "CREATE DATABASE skynotify ENCODING 'UTF-8';"
-d explicitly declares which database to use as the default for SQL statements that don't explicitly include a db name during this interactive session.
BASICS FOR GETTING A CLEAR PICTURE OF WHAT YOUR PostgresQL SERVER has in it.
You must connect to an existing database to use psql interactively. Fortunately, you can ask psql for a list of databases:
psql -l
.
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
----------------------------------+-----------+----------+-------------+-------------+-------------------
skynotify | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
myapp_dev | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
ruby-getting-started_development | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/skynotify +
| | | | | skynotify=CTc/skynotify
template1 | skynotify | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/skynotify +
| | | | | skynotify=CTc/skynotify
(6 rows)
This does NOT start the interactive console, it just outputs a text based table to the terminal.
As another answers says, postgres is always created, so you should use it as your failsafe database when you just want to get the console started to work on other databases. If it isn't there, then list the databases and then use any one of them.
In a similar fashion, select tables from a database:
psql -d postgres -c "\dt;"
My "postgres" database has no tables, but any database that does will output a text based table to the terminal (standard out).
And for completeness, we can select all rows from a table too:
psql -d ruby-getting-started_development -c "SELECT * FROM widgets;"
.
id | name | description | stock | created_at | updated_at
----+------+-------------+-------+------------+------------
(0 rows)
Even if there are zero rows returned, you'll get the field names.
If your tables have more than a dozen rows, or you're not sure, it'll be more useful to start with a count of rows to understand how much data is in your database:
psql -d ruby-getting-started_development -c "SELECT count(*) FROM widgets;"
.
count
-------
0
(1 row)
And don't that that "1 row" confuse you, it just represents how many rows are returned by the query, but the 1 row contains the count you want, which is 0 in this example.
NOTE: a db created without an owner defined will be owned by the current user.
had the problem with using the JDBC driver, so one just has to add the database (maybe redundantly depending on the tool you may use) after the host name in the URL, e.g.
jdbc:postgres://<host(:port)>/<db-name>
further details are documented here: http://www.postgresql.org/docs/7.4/static/jdbc-use.html#JDBC-CONNECT
Connect to postgres via existing superuser.
Create a Database by the name of user you are connecting through to postgres.
create database username;
Now try to connect via username
This worked for me when solving this problem
i ran sudo -i -u postgress --> to gain access to my postgres database.
Then enter your password.
it would allow you to now enter psql
which would prompt you for other command
Cheers!
Had this problem when installing postgresql via homebrew.
Had to create the default "postgres" super user with:
createuser --interactive postgres answer y to for super user
createuser --interactive user answer y to for super user
you can set the database name you want to connect to in env variable PGDATABASE=database_name. If you dont set this psql default database name is as username. after setting this you don't have to createdb
Was running postgres in docker. In cli I was getting the error "root" role doesn't exist.
su - postgres
psql
solved the problem.
PostgreSQL has its own user on the system which is created when PostgreSQL is installed. The postgres user is able to log into PostgreSQL without using a password. No other user is able to log into PostgreSQL.
This means that before using PostgreSQL, you will need to switch to that user account with the command:
su - postgres
You will then be able to log into the PosgreSQL client with the command:
psql
You will not be able to access the database from the command line as any other user.
I still had the issue above after installing postgresql using homebrew - I resolved it by putting /usr/local/bin in my path before /usr/bin
This is a basic misunderstanding. Simply typing:
pgres
will result in this response:
pgres <db_name>
It will succeed without error if the user has the permissions to access the db.
One can go into the details of the exported environment variables but that's unnecessary .. this is too basic to fail for any other reason.