How to batch create PostgreSQL databases? - postgresql

How can one batch create many PostgreSQL databases and users, one database for each user?
I have a list of linux usernames, and I need to create a new postgres user for each linux username, and then an exclusive database for the new user in the home folder which no other users can see except the root.
I know how to use CREATE DATABASE but am not very familiar with loops etc. in PostgreSQL. Any pointers are appreciated.

One way is to make a shell script like db.sh
#!/bin/sh
users="foo bar baz"
for user in $users
do
PGUSER=pguser createdb $user
done
Then do a
chmod 0755 db.sh
And execute it with
./db.sh
You may have to change PGUSER to your environment.
Shell loops:
http://www.tutorialspoint.com/unix/unix-loop-control.htm

Do it from the shell, it will be a lot less work:
$ for user in $(cat usernames.txt); do
createuser -e $user
createdb -e -O $user $user
done;
Incidentally, for random Postgres commands, you can use psql -c to run SQL from the command line non-interactively.

Related

What is the role of -s flag in creating user

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.

Script to create postgres user with whoami

I'm making a script to automate the process to install and create a new postgres user, the problem is that I will not ever know the name of the local user where the script will run, so I tried this with no results:
LOCALUSER=whoami
sudo su - postgres -c "psql -U postgres -d template1 -c \"create user ${LOCALUSER} with createdb;\""
It creates a new user but named "whoami", as you could guess, I need the current user name instead "whoami".
How can I pass the user name?
Thank you in advance!
Best Regards
Alejandro
Using:
LOCALUSER="$(whoami)"
Instead of:
LOCALUSER=whoami
Did the trick.
Source: https://unix.stackexchange.com/questions/175415/forward-function-and-variables-into-sudo-su-user-eof

PostgreSQL - read an SQL file into a PostgreSQL database from the commandline

I use Ruby to generate a bunch of SQL commands, and store this into a file.
I then login to my PostgreSQL database. Then I do something like:
\i /tmp/bla.sql
And this populates my database.
This all works fine as it is, no problem here.
I dislike the manual part where I have to use \i, though (because I need this to work in a cron job eventually, and I think commands like \i are only available when you are directly in the interactive psql prompt).
So my question now is:
Is it possible to use a psql command from the command line that directly will start to read in an external file?
You can directly use the psql command as shown below.
Works for me with Ubuntu and Mint. On Windows it should be quite the same...
psql -U user -d database -f filepath
Example:
psql -U postgres -d testdb -f /home/you/file.sql
For more information take a lock at the official documentation: http://www.postgresql.org/docs/current/static/app-psql.html
When you try to execute an sql file using cron, you will also need to set the environment - database name, password etc. This is a short shell script snippet that does it all
source /var/lib/pgsql/scripts/.pgenv
echo $PATH
psql << AAA
select current_date;
select sp_pg_myprocedure(current_date);
AAA
In .pgenv, you set the values such as
export PGPORT=<yourport>
export PGHOST=<yourhost>
export PGDATA=<yourdatadir>
Also have a .pgpass file so that the password is supplied.
http://www.postgresql.org/docs/current/static/libpq-pgpass.html
Replace the part where SELECT is being done with whatever you want to do, or do it as #Kuchi has shown.

Creating role and database PostgreSQL not working

First I run the command:
sudo su _postgres
Then I run the command:
create role mixeddrinks with createdb login password 'password1'
But it comes back with:
-bash: create: command not found
I’m not very familiar with the Terminal and with PostgreSQL so I’m not sure what I am doing wrong I am trying to create a role and a database.
First I run the command sudo su _postgres, then I run the command create role mixeddrinks with createdb login password 'password1'
You're mixing up shell commands and the psql command line.
If you want to use SQL, you need to use the psql command. sudo su _postgres is an inefficient way of getting a unix command shell as the _postgres user. It doesn't give you an SQL shell. You can run unix commands like psql, createuser, etc from the unix command shell. You can tell you're at the command shell because the prompt looks something like:
postgres$
If you want an SQL shell, so you can run commands like CREATE USER, etc, you need to run psql. If you want a superuser SQL shell, that'd be something like:
sudo -u _postgres psql
This will give you a prompt like:
postgres=#
where you can run SQL commands. Remember that SQL commands end with a semicolon.
postgres=# create role mixeddrinks with createdb login password 'password1';

How to execute PostgreSQL script-file from command line without userinput / password

During the installation of my app, I want to create a PostgreSQL-Database and some tables and functions.
For that purpose I use PSQL.EXE that ships with PostgreSQL. I have 2 scripts. The first one creates the database and a corresponding user that has rights to execute scripts on that database. I want to execute the second script as this just created user. Unfortunately I can't find a way to pass the password for that user as a command line argument. Omitting the password leads to a stop of execution and a prompt for the user to enter the password, which I would like to avoid - since this is executed during installtion of my app.
Is there any way to pass the password as argument or is there any other command line tool I could use?
To explain the environment a bit further. I use WiX 3.5 setup as a "MSI-Builder".
You can either use a pgpass file as dbenhur answerd, or you can set the environment variable PGPASSWORD before calling psql:
SET PGPASSWORD=my_very_secret_password
psql somedb someuser
All supported environment variables are documented in the manual: http://www.postgresql.org/docs/current/static/libpq-envars.html
You can't supply password via cmdline arg (and don't want to as that's poor security practice).
You can provide a .pgpass file to support automatic script authentication. Here's the docs.
Better still, if you have access to create the db role then you already have all the access you need without having to carefully log in with a password. Have the second script operate under the same user as the first but include the following line to switch user:
set role my_new_user;
Where my_new_user is the name of the role you want to run it as.
If you only divided the scripts because of the different logins then with this they can go in the same file and just switch role mid way through.
Note:
On the off chance that you are not creating the DB and new role as a super user this may be a little more complex. If this is the case you will need to create the new role with:
create role my_new_role ... ADMIN my_role;
Where my_new_role is the role you're creating and my_role is your current user. Then when you're finished simply:
revoke my_new_role from my_role;
For completion, you can also use URI (doc link)
List dbs
psql "postgresql://username:password#localhost/postgres" -l
I also crafted this command to have only names (please tell me if you know a better way):
psql "postgresql://username:password#localhost/postgres" -l | awk -F '|' '{print $1}'| sed -e '/^\s*$/ d' -e '1,3d'|sed '$d'|awk '{print $1}'
You can also use unix socket to connect:
# ss -x -a |grep postgres|awk '{print $5}'
/var/run/postgresql/.s.PGSQL.5432
Note that the parent directory of the socket is used:
# sudo -u postgres psql -d "postgresql:///postgres?host=/var/run/postgresql/" -l
You can only do this if you have this line in your pg_hba.conf:
local all postgres ident
"ident" uses unix user for authent
dump a db
Here I added a different port number
pg_dump -Fc "postgresql://username:password#localhost:9001/${db}" > "backup_${db}.pgdump"
With dumpall you need a super user or role (with CREATE ROLE ... SUPERUSER). And it must have access to all DB. By default postgres can.
but in my case I couldn't use pg_dumpall with postgres because his password was removed by devs.
So I used:
sudo -u postgres pg_dumpall -d "postgresql:///?host=/var/run/postgresql/" > all.dump
tested version
# cat /opt/postgresql/PG_VERSION
9.6
hth