PostgreSQL 13 :: ERROR: permission denied for table 'mydb' - postgresql

Below I'm creating database mydb and populating it. Notice that the last step I perform is setting the password for postgres. This is simply to avoid password prompts during previous steps.
I followed steps in other StackOverflow posts, namely issuing the GRANT ALLs on TABLES, SEQUENCES and FUNCTIONS, but am still facing the below issue.
mydb.sh:
su - postgres <<xEOFx
set +H
psql -c "CREATE DATABASE mydb"
psql -c "CREATE USER user01 WITH ENCRYPTED PASSWORD 'SomePassword'"
psql -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public to user01"
psql -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public to user01"
psql -c "GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public to user01"
psql --dbname=mydb --username=postgres -f /tmp/mydb.sql
psql -c "GRANT ALL PRIVILEGES ON DATABASE mydb TO user01"
psql -c "ALTER USER postgres WITH PASSWORD 'AnotherPassword'"
exit
xEOFx
The script does not fail, but I also cannot access the mydb as user01:
jdoe$ psql --username=user01 --dbname=mydb
Password for user user01:
psql (13.2)
Type "help" for help.
mydb=> \c
You are now connected to database "mydb" as user "user01".
mydb=> \dt
List of relations
Schema | Name | Type | Owner
--------+---------------+-------+----------
public | some_table | table | postgres
(1 rows)
mydb=> select * from some_table;
ERROR: permission denied for table some_table
mydb=>
SIDEBAR: I do notice that the owner of some_table is postgres, and would prefer that it be user01. Perhaps this could be part of the issue.
What am I missing?
Thank you in advance.
EDIT: Note that I tried running psql --dbname=mydb --username=postgres -f /tmp/mydb.sql before the GRANT ALL statements, too.

You are granting privileges to tables, sequences, and functions in the public schema in the database postgres, not mydb. By default, psql will connect to the database named the same as the current user, which is postgres in this case. Make sure you run the commands in mydb by adding -d mydb to your psql commands.

Related

Restoring the Dump using PostgreSQL's psql

I'm trying to restore the DB from an SQL file using
psql dbname < dumpfile
but after I connect to my DB psql provides a prompt with the name of the database to which psql is currently connected, followed by the string =>. For example:
testdb=>
So how can I enter the command, or which Meta-Command should I use to restore the DB with the psql command? (Already connected to my DB)
psql is the command line client. You cannot call psql when you are already in an interactive psql session.
Either you connect with psql -d testdb in an interactive session and import the dump with \i dumpfile, or you stay on the shell and call psql in a non-interactive session with the dump file as script: psql -d testdb -f dumpfile
you can use \c <database_name>
it will connect you to the desired database
for example
global=> \l
List of databases
Name | Owner | Encoding
test | pgadmins | UTF8
global=> \c test
You are now connected to database "test" as user "user1".
test=>

Postgres - npm script to drop/add database

I want to simplify my life and automate the process of adding/dropping my test db via an npm script, however I am running into issues.
Attempt 1:
"drop-db:local": "psql postgres \"drop database blog_db; create database blog_db; \\c blog_db; CREATE EXTENSION \"pgcrypto\";\""
After running this, I keep getting the following error
psql: error: could not connect to server: FATAL: Peer authentication failed for user "drop database blog_db; create database blog_db; \c "
Attempt 2:
changed
psql postgres
to
psql -h localhost -U rm postgres
So this opens the db in my terminal but that seems to ignore some stuff as mentioned in the msg below
psql: warning: extra command-line argument "drop database blog_db; create database blog_db; \c blog_db; CREATE EXTENSION pgcrypto;" ignored
What am I doing wrong?
This is a list of my db users
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
rm | Superuser, Create DB | {}
db version: psql (12.2 (Ubuntu 12.2-2.pgdg18.04+1))
You need to use -c or -f with your psql command.
As the psql help shows:
-c, --command=COMMAND run only single command (SQL or internal) and exit
-f, --file=FILENAME execute commands from file, then exit
As you are using multiple commands so it will be better of you use -f followed by a sql file name that has all the commands e.g your drop_create_db.sql file can have following code:
drop database blog_db;
create database blog_db;
\c blog_db;
CREATE EXTENSION "pgcrypto";
And you may run this file by using the following command
"drop-db:local": psql -U postgres -d postgres -p 5432 -f /tmp/drop_create_db.sql

postgresql: run SQL commands using psql in commandline

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.

Relation does not exist when trying to grant privileges

I'm currently writing a script to build my vagrant box. I got PHP 7 and some other tools installed, as well as PostgreSQL, but when creating the database and trying to grant privileges I'm getting the following error
ERROR: relation "projectname" does not exist
This is my script (the important stuff)
#!/usr/bin/env bash
projectname='projectname'
echo "Initializing database"
sudo apt-get install -y postgresql
sudo -u postgres psql -c "CREATE USER $projectname WITH PASSWORD 'xxxx';"
sudo -u postgres psql -c "CREATE DATABASE $projectname;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON $projectname TO $projectname;"
Everything works until the last step
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON $projectname TO $projectname;"
When trying this out, I'm getting the above error. I also tried to write it manually
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON projectname TO projectname;"
Same error.
I also tried to wrap it in quotation marks
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON 'feedparser' TO 'feedparser';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON \"feedparser\" TO \"feedparser\";"
What exactly am I doing wrong here?
Documentation about GRANT PRIVILEGES says that your version GRANT command is suitable for grant rights to table. If you want to grant rights to database you should use GRANT ALL PRIVILEGES ON DATABASE projectname TO projectname;. Below I show the results of this commands:
postgres=# CREATE USER projectname WITH PASSWORD 'projectname';
CREATE ROLE
postgres=# CREATE DATABASE projectname;
CREATE DATABASE
postgres=# GRANT ALL PRIVILEGES ON projectname TO projectname;
ERROR: relation "projectname" does not exist
postgres=# GRANT ALL PRIVILEGES ON DATABASE projectname TO projectname;
GRANT

psql telling me "database does not exist" in some places, recognizing it in others

I'm trying to run these commands from this tutorial (http://jamiecook.wordpress.com/2011/11/24/setting-up-postgresql-postgis-for-rails-on-ubuntu/)
sudo su - postgres
createdb -E UTF8 template_postgis # Create the template spatial database.
createlang -d template_postgis plpgsql # Adding PLPGSQL language support.
psql -d osm -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql
psql -d osm -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql
cat <<EOS | psql -d template_postgis
UPDATE sample_postgis_db SET datistemplate = TRUE WHERE datname = 'template_postgis';
REVOKE ALL ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE public.geometry_columns TO PUBLIC;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE public.spatial_ref_sys TO PUBLIC;
GRANT ALL ON geometry_columns TO PUBLIC;
GRANT ALL ON geography_columns TO PUBLIC;
GRANT ALL ON spatial_ref_sys TO PUBLIC;
VACUUM FULL FREEZE;
EOS
and am getting the error:
ERROR: relation "sample_postgis_db" does not exist
LINE 1: UPDATE sample_postgis_db SET datistemplate=TRUE WHERE datnam...
But it certainly does exist:
psql -d postgres
\list
#=>
...
sample_postgis_db | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
...
I can login to it:
psql -d sample_postgis_db
but even when I run that UPDATE line (nonsensically of course, but its a good test I think) inside of the db's psql, it still doesn't recognize itself.
sample_postgis_db=# UPDATE sample_postgis_db SET datistemplate=TRUE WHERE datname = "template_postgis";
ERROR: relation "sample_postgis_db" does not exist
LINE 1: UPDATE sample_postgis_db SET datistemplate=TRUE WHERE datnam...
The tutorial has:
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';
that you replaced by this:
UPDATE sample_postgis_db SET datistemplate = TRUE WHERE datname = 'template_postgis';
This replacement is uncalled for, since what is updated here is a system table, not a database name.
I hate how mysterious this is...and maybe its just because I altered sample_postgis_db's role to SUPERUSER (out of desperation), but it just started working...