PostGIS only works with root user - postgresql

I have a database and am trying to use PostGis with it.
When I run:
$ psql -h localhost -d $APP_DB_NAME -U $APP_DB_USER
# SELECT PostGIS_version();
I get the following error:
ERROR: function postgis_version() does not exist
LINE 1: SELECT PostGIS_version();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
But when I enter the database as root:
$ sudo su postgres -c psql $APP_DB_NAME
# SELECT PostGIS_version();
It runs fine:
postgis_version
---------------------------------------
2.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)
I am installing the PostGis extension as the root user, since my user doesn't have super_user access.
$ su - postgres -c psql $APP_DB_NAME
# CREATE EXTENSION postgis;

My guess is that the owner of the schema in which postgis is installed is not the user you're logging in as, but rather the "root" user (which is postgres).
$ psql postgres
postgres=# \dn
List of schemas
Name | Owner
--------------------+----------
public | postgres
pg_catalog | postgres
my_data | someuser
When connecting as postgres, postgis will work in this case, but if you connect as any other user, it will fail, and say it's not there, even though if you try to create extension postgis it will say it's installed already.
To correct this, make sure all the schemas are owned by the user you're actually connecting as:
ALTER SCHEMA public OWNER TO my_user;

Related

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

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.

How to create user in postresql version 12?

I have loged in postresql as default postgres user:
psql -U postres
and following the official documentation: https://www.postgresql.org/docs/12/app-createuser.html I have type this:
create user -d -e --role=myrole -r -s myuser;
and nothing happens. Postresql ignores the command.
\du
does not return myuser in user list.
It ignores the command when added any option, only this works:
create user myuser;
CREATE USER is a SQL statement that has its own syntax https://www.postgresql.org/docs/12/sql-createuser.html whereas createuser is an executable that has a different syntax: https://www.postgresql.org/docs/12/app-createuser.html: you cannot mix them.

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

PostGIS type "geometry" doesn't exist when pg_dump copying database to server

Similar question to many that have already been asked, but I have yet to find a solution.
I'm copying a Postgres db from my local machine to a server using:
pg_dump -C -h localhost -U localuser dbname | psql -h remotehost -U remoteuser dbname
However, whenever I try to execute this, any tables with PostGIS geography columns are skipped and not copied over, and I'm left with the following error:
ERROR: type "<mydb>.geography" does not exist
Attempted solutions:
On this server, I have successfully installed PostGIS and created the relevant extensions:
mydb=# select postgis_version();
postgis_version
---------------------------------------
2.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)
Additionally, geometry is a recognized data type:
mydb=# \dT *.geometry
List of data types
Schema | Name | Description
--------+----------+-----------------------------------------
public | geometry | postgis type: Planar spatial data type.
(1 row)
My search_path includes everything relevant:
mydb=# show search_path;
search_path
------------------------
mydb, public, postgis
and
mydb=# SELECT r.rolname, d.datname, rs.setconfig
FROM pg_db_role_setting rs
LEFT JOIN pg_roles r ON r.oid = rs.setrole
LEFT JOIN pg_database d ON d.oid = rs.setdatabase
WHERE r.rolname = 'mydb' OR d.datname = 'mydb';
rolname | datname | setconfig
---------+---------+----------------------
| mydb | {search_path=public}
(1 row)
My only guess as to what might be causing this headache is that the superuser on my local machine isn't the same name as the remote superuser. I.e., localuser and remoteuser don't match.
The rest of the answer assumes that the error you quote is the first error while restoring the dump. If not, it might be the consequence of an earlier error (e.g., failure to CREATE EXTENSION postgis).
If PostGIS is installed on both servers, the message suggests that it is installed in different schemas on both databases.
Examine the result of
\dx postgis
on both databases to check.
Since PostGIS is not a relocatable extension, you have to drop and re-create it to move it to a different schema.

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