I'm trying to write a bash script that will create a Postgres database, as well as the user and the user privileges to access that database. I'm using Postgres 9.6. I have the below ...
create_db_command="SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec"
drop_owned_by_command="DROP OWNED BY $DB_USER;"
drop_role_command="DROP ROLE IF EXISTS $DB_USER;"
create_user_command="create user $DB_USER with encrypted password '$DB_PASS';"
grant_privs_command="grant all privileges on database $DB_NAME to $DB_USER;"
PGPASSWORD=$ROOT_PASSWORD
# This command creates the db if it doesn't already exist
echo "SELECT 'CREATE DATABASE $DB_NAME' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '$DB_NAME')\gexec" | psql -U$PG_USER
psql -U$PG_USER $DB_NAME -c "$drop_owned_by_command"
psql -U$PG_USER -c "$drop_role_command"
psql -U$PG_USER -c "$create_user_command"
psql -U$PG_USER -c "$grant_privs_command"
The problem is when the script is run the very first time, the command
DROP OWNED BY $DB_USER;
fails because the user does not yet exist. Is there a way to write the above command so that it will only run if the user exists? Similar to DROP USER IF EXISTS ..., but DROP OWNED has no IF EXISTS clause.
You can use a similar technique like you already have for CREATE DATABASE.
In the shell:
drop_owned_by_command="SELECT 'DROP OWNED BY $DB_USER' FROM pg_roles WHERE rolname = '$DB_USER'\gexec"
echo $drop_owned_by_command | psql -U$PG_USER $DB_NAME
The SELECT only returns a row (containing the DDL command) if the role a actually exists. This is in turn executed by the psql command \gexec.
So we have a combination of SQL and psql commands and cannot use psql -c since, quoting the manual on --command:
command must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features),
or a single backslash command. Thus you cannot mix SQL and psql
meta-commands within a -c option.
Instead, pipe the echo to psql like demonstrated - and like suggested in the manual and in my related answer below and like you already do for CREATE DATABASE.
Related:
Simulate CREATE DATABASE IF NOT EXISTS for PostgreSQL?
Shell script to execute pgsql commands in files
I have the below three lines to be run in commandline using psql how can i do it.
CREATE DATABASE myproject;
CREATE USER myprojectuser WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
I just want to pass the sql strings as it is.
As per the docs psql -c 'command;'
psql -c 'CREATE DATABASE myproject;' -c "CREATE USER myprojectuser WITH PASSWORD 'password';" -c 'GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;'
As #horse suggested -f filename is a better option. You can also put them into a variable using a here document and execute it with the -c option .
read -r -d '' my_sqls << EOM
CREATE DATABASE myproject;
CREATE USER myprojectuser WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
EOM
psql -c "$my_sqls" # running all the lines.
I search to create a database via CMD, i success to create it using this command:
C:\>"C:\Program Files\PostgreSQL\9.3\bin\psql.exe" -U postgres template1
So when i excute this command i can Create my database like this:
template1=# CREATE DATABASE d_base;
My objectif is to create this database with just one line:
like this:
C:\>"C:\Program Files\PostgreSQL\9.3\bin\psql.exe" -U postgres template1 "CREATE DATABASE T;"
But this not work with me, it gave me this error:
i can solve this problem with creating a .bat Script but my objectif is to use just one line,
Is there any solution for that.
Thank you.
You get that error because template1 is not the last argument. You can use -d to specify the database.
Use the database postgres instead of template1.
Try this:
"C:\Program Files\PostgreSQL\9.3\bin\psql.exe" -U postgres -d postgres -c "CREATE DATABASE t"
https://www.postgresql.org/docs/9.3/static/app-psql.html
see --command=command section
I am trying to a create a user in postgres, I did the following.
sudo -u postgres createuser mystore
But I found out that I should use -s flag while creating the user, So my question is what is role of -s flag while creating user.
And I tried to remove the user by the following steps
sudo -u postgres psql
drop user mystore
Then tried to create the store with the -s flag, it says
role "mystore" already exists.
How to handle this
createuser -s will give the new user superuser privileges. As with most command-line tools in Linux, you can get a description of each flag by running createuser --help.
The problem in psql appears to be a missing semicolon after your drop command. psql supports multi-line statements, so hitting Enter will simply add a new line; it won't submit the command to the server until it sees a semicolon terminator.
In MySQL, I used use database_name;
What's the psql equivalent?
In PostgreSQL, you can use the \connect meta-command of the client tool psql:
\connect DBNAME
or in short:
\c DBNAME
You can connect to a database with \c <database> or \connect <database>.
At the PSQL prompt, you can do:
\connect (or \c) dbname
You can select the database when connecting with psql. This is handy when using it from a script:
sudo -u postgres psql -c "CREATE SCHEMA test AUTHORIZATION test;" test
use \c databaseName or \connect databaseName
(Working on psql 13.3)
\l for databases
\c DatabaseName to switch to db
\df for procedures stored in particular database
Though not explicitly stated in the question, the purpose is to connect to a specific schema/database.
Another option is to directly connect to the schema. Example:
sudo -u postgres psql -d my_database_name
Source from man psql:
-d dbname
--dbname=dbname
Specifies the name of the database to connect to. This is equivalent to specifying dbname as the first non-option argument on the command line.
If this parameter contains an = sign or starts with a valid URI prefix (postgresql:// or postgres://), it is treated as a conninfo string. See Section 31.1.1, “Connection Strings”, in the
documentation for more information.
Using psql's meta-command \c or \connect [ dbname [ username ] [ host ] [ port ] ] | conninfo (see documentation).
Example: \c MyDatabase
Note that the \c and \connect meta-commands are case-sensitive.
Use below statement to switch to different databases residing inside
your postgreSQL RDMS
\c databaseName
You can also connect to a database with a different ROLE as follows.
\connect DBNAME ROLENAME;
or
\c DBNAME ROLENAME;
You can connect using
\c dbname
If you would like to see all possible commands for POSTGRESQL or SQL follow this steps :
rails dbconsole
(You will be redirected to your current ENV database)
?
(For POSTGRESQL commands)
or
\h
(For SQL commands)
Press Q to Exit
If you want to switch to a specific database on startup, try
/Applications/Postgres.app/Contents/Versions/9.5/bin/psql vigneshdb;
By default, Postgres runs on the port 5432. If it runs on another, make sure to pass the port in the command line.
/Applications/Postgres.app/Contents/Versions/9.5/bin/psql -p2345 vigneshdb;
By a simple alias, we can make it handy.
Create an alias in your .bashrc or .bash_profile
function psql()
{
db=vigneshdb
if [ "$1" != ""]; then
db=$1
fi
/Applications/Postgres.app/Contents/Versions/9.5/bin/psql -p5432 $1
}
Run psql in command line, it will switch to default database; psql anotherdb, it will switch to the db with the name in argument, on startup.
Listing and Switching Databases in PostgreSQL
When you need to change between databases, you’ll use the \connect command, or \c followed by the database name as shown below:
postgres=# \connect database_name
postgres=# \c database_name
Check the database you are currently connected to.
SELECT current_database();
PostgreSQL List Databases
postgres=# \l
postgres=# \list
Connect to database:
Method 1 : enter to db : sudo -u postgres psql
Connect to db : \c dbname
Method 2 : directly connect to db : sudo -u postgres psql -d my_database_name
You can just enter use [dbName] to switch between databases without reentering your password.