postgis not available for all postgres users - postgresql

When creating a new user on our Potgis enabled database I run into the strange issue that that new user cannot access the postgis extension while earlier created users can.
With my user account I get the following output:
mydb => SELECT postgis_version();
postgis_version
---------------------------------------
2.3 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)
With the new user I get the following:
mydb => SELECT postgis_version()
mydb-> ;
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.
Also QGIS is giving me hint that postgis is not active:
2018-01-23T16:38:13 1 No PostGIS support in the database.
I am connecting to the exact same database.
The user does have access to the public schema and to the geometry_columns table.
I am a bit lost here since according to my info Postgis is an extansion on the database level and it should be there for all users.

The PostGIS extension must be installed in a schema that must also be in the user search path.
You can check where it is installed with the command
select e.extname,n.*
from pg_extension e, pg_namespace n
where e.extnamespace = n.oid and e.extname='postgis';
And you can check if the schema where it is installed is in the user search path by issuing
show search_path;
If not, you can permanently add the path by altering the user.
ALTER USER username SET search_path TO "$user", public, postgis_schema;
As the previous command takes effect at the next login only, you can apply it immediately by applying
SET search_path TO "$user", public, postgis_schema;

Related

Non-SuperUser Database Management

I am using the PostgreSql manual and other guides to setup my database environment.
So far things are looking good, but I am wondering if I have a problem.
I am trying to apply this:
Tip It is good practice to create a role that has the CREATEDB and CREATEROLE privileges, but is not a superuser, and then use this role for all routine management of databases and roles. This approach avoids the dangers of operating as a superuser for tasks that do not really require it.
I have already created a user for this role.
createuser --interactive --pwprompt
Enter name of role to add: Manager
Enter password for new role:
Enter it again:
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) y
...and connected to an already existing database as the new user (Manager) Or so I thought.
psql -d test
Password for user postgres:
psql (11.2)
WARNING: Console code page (437) differs from Windows code page (1252)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
Type "help" for help.
test=# \c test Manager
Password for user Manager
WARNING: Console code page (437) differs from Windows code page (1252)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
You are now connected to database "test" as user "Manager".
test=>
I created a table for the database "test", but on checking it,the Owner isn't Manager, but postgres.
test=> \dt
List of relations
Schema | Name | Type | Owner
--------+---------------+-------+----------
public | Data-projects | table | postgres
(1 row)
test=> \dn
List of schemas
Name | Owner
--------+----------
public | postgres
(1 row)
I am not sure if this is good. I expected the owner to be Manager.
This is my first time using these tools. Can someone guide me in the right direction, please?
I want Manager to manage all the databases.
Wouldn't that make him owner?
Thanks
Database test is not owned by Manager because it was created by user postgres. The user who created an object will be its owner.
However, a superuser can transfer ownership:
ALTER DATABASE test OWNED BY "Manager";
I'll give you some additional tips:
Only use lower case letters, numbers and _ in the names of objects and users, because otherwise you always have to user double quotes for them in SQL, like I did above. That leads to needless suffering.
Run the following to make the database more secure:
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
Create a new schema that will hold the objects for your application:
CREATE SCHEMA myapp;
Set the search_path appropriately:
ALTER DATABASE test SET search_path = myapp, public;

Is "postgres" a default and special user of PostgreSQL?

Chapter 21. Database Roles lists the default roles of PostgreSQL. But I don't find user postgres there,
which has been created by default in PostgreSQL. Is postgres a
default role? Does the manual miss it or do I misunderstand?
In PostgreSQL, is postgres a special user, or a regular user just
like one created manually? Does the PostgreSQL server need the user postgres? Will removing it cause some trouble to the server or something else?
The following two commands run in psql provide default roles or
usernames, which both include postgres. Why do they differ?
# select usename from pg_catalog.pg_user;
usename
----------
postgres
(1 row)
# select rolname from pg_catalog.pg_roles;
rolname
----------------------
postgres
pg_monitor
pg_read_all_settings
pg_read_all_stats
pg_stat_scan_tables
pg_signal_backend
(6 rows)
postgres is not a default role.
When you create the PostgreSQL database cluster with initdb, you can specify the name of the installation superuser with the -U option. If you omit that option, the name of the superuser will be the same as the name of the operating system user you are using.
Since it is customary to have initdb PostgreSQL run by an operating system user postgres, the superuser is usually called postgres too, but that isn't in any way required.
postgres is just a normal superuser like any other.
You will have trouble dropping it because it owns all the system objects, and you cannot easily modify those objects. You are advised not to try.
pg_read_all_settings and the others don't show up in pg_user because they are not login roles.
postgres is the first user that is available after an installation. it is a super user. But, it is possible to define your own super users which will have equivalent permissions to the postgres user.
A user is a role that has the ability to log in.
Roles without login privilege are used for various system level uses and are sometimes also used to manage access control rules through inheritance (e.g. you may have a role analysts and a user hal that is granted membership to the analysts role)
Thus pg_user only returns those roles that are able to log into the database.

Unable to delete PostgreSQL role

Yesterday I created a user to make backups from PostgreSQL. I granted select to this user and then I noticed that the name was not well written. The problem is that I tried to erase the user using the command line and the response was, due to the grants that I made a few moments back:
ERROR: role "dump_user" cannot be dropped because some objects depend on it
Long story short, I erased this user using pgadmin and now I have problems because when I want to create a new table, it tells:
ERROR: role 313898229 was concurrently dropped
I cheked and 313898229 was the oid of this dump_user in the pg_authid table, I tried to create a new user and assign this oid, but postgres says that I can't modify system id "oid".
Is there a way that I can permanently erase this user?
If all you wanted was a different name:
ALTER ROLE dump_user RENAME TO better_name;
Too late for that now. Before deleting the role you should have run:
REASSIGN OWNED BY pg_dump TO postgres; -- postgres being default superuser role
Read details here:
Find objects linked to a PostgreSQL role
Your error message:
ERROR: role 313898229 was concurrently dropped
is defined in the source code here. Looks like a race condition between two transactions. But you omitted relevant details.

Allowing a user to access a table in DB2

I'm using DB2 10.5 and have two users: db2admin and db2user. db2admin is an Administrator of the Windows 7 Operating System while db2user is a normal user. I have created a database named DB1 using db2admin and now I want to allow db2user to access the TB1 table in it.
I used the following command for that:
db2 => connect to db1 user db2admin using db2admin
db2 => grant select, insert, update, delete on tb1 to user db2user
The Result when executed following commands:
connect to db1 user db2user using db2user
SELECT * FROM SYSIBMADM.PRIVILEGES WHERE AUTHID = SESSION_USER AND AUTHIDTYPE = 'U'
AUTHID AUTHIDTYPE PRIVILEGE GRANTABLE OBJECTNAME
DB2USER U UPDATE N TB1
DB2USER U SELECT N TB1
DB2USER U INSERT N TB1
DB2USER U DELETE N TB1
According to that result set db2user seems to have privileges to the TB1. However, when I tried to access it programmatically using db2user, following error was thrown:
DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=DB2USER.TB1
According to the error code there is no TB1 in the DB2USER schema.
Following commands confirmed that:
connect to db1 user db2user using db2user
db2 => list tables
0 record(s) selected.
What am I missing or doing wrong? Any guidance on how to get this working is much appreciated.
UPDATE: I have already tried accessing the same table with db2admin and it works perfectly. What I want to get done is to access it using db2user, but db2user shouldn't create the tables; that's db2admin's job. So how can I get that working? How can db2admin put the tables inside db2user's schema?
SQLCODE -204 means that the object cannot be found. My guess is that since you didn't provide a schema, your table was implicitly placed in the db2admin schema. Try doing
SELECT * FROM db2admin.tb1
And see if that works.
You created the table from user DB2ADMIN and the implicit schema will be used. In this case, the table is called db2admin.tb1
When you perform a select from the DB2USER, the implicit schema is the same user name, and that table does not exist.

Postgis installation: type "geometry" does not exist

I am trying to create table with Postgis. I do it by this page. But when I import postgis.sql file, I get a lot of errors:
ERROR: type "geometry" does not exist
Does anybody know how can I fix it?
I had the same problem, but it was fixed by running following code
CREATE EXTENSION postgis;
In detail,
open pgAdmin
select (click) your database
click "SQL" icon on the bar
run "CREATE EXTENSION postgis;" code
If the Postgis-Extension is loaded, then your SQL perhaps does not find the geometry-type because of missing search-path to the public schema.
Try
SET search_path = ..., public;
in the first line of your scsript. (replace ... with the other required search-paths)
You can do it from terminal:
psql mydatabasename -c "CREATE EXTENSION postgis";
To get psql to stop on the first error, use -v ON_ERROR_STOP=1 (which is off by default, which is why you see many errors). For example:
psql -U postgres -d postgis -v ON_ERROR_STOP=1 -f postgis.sql
The actual error is something like "could not load library X", which can vary on your situation. As a guess, try this command before installing the sql script:
ldconfig
(you might need to prefix with sudo depending on your system). This command updates the paths to all system libraries, such as GEOS.
This error may also occur if you try to use postgis types on another schema rather than public.
If you are creating you own schema, using postgis 2.3 or higher and encounter this error, do the following as stated here:
CREATE SCHEMA IF NOT EXISTS my_schema;
CREATE extension postgis;
UPDATE pg_extension
SET extrelocatable = TRUE
WHERE extname = 'postgis';
ALTER EXTENSION postgis
SET SCHEMA my_schema;
ALTER EXTENSION postgis
UPDATE TO "2.5.2next";
ALTER EXTENSION postgis
UPDATE TO "2.5.2";
SET search_path TO my_schema;
Then you can proceed to use postgis functinalities.
You must enable the extension on your database.
psql my_database -c "CREATE EXTENSION postgis;"
You also need to ensure that the user you are trying to use the postgis extension as, has access to the schema where postgis is setup (which in the tutorials I read is called 'postgis').
I just had this error, and it was solved because I had only given a new user access to the database. In the database I'd created, I ran:
grant all on schema postgis to USERNAME;
And this solved this error
run this query first:
"CREATE EXTENSION postgis"
The answers here may solve your problem, however if you already have postgis enabled on your DB, the issue may be that you are trying to restore a postgis table (with a geometry column) into a schema other than where your postgis extension is enabled. In pgAdmin you can click on the postgis extension and see which schema is specified. If you are trying to restore a table with geometry column into a different schema, you might get this error.
I resolved this by altering my postgis extension - however I'm not sure if that was necessarily the best way to do it. All I know is that it allowed me to restore the table.
First make sure you have (matching to pg version: psql -V) postgis installed:
sudo apt install postgis postgresql-9.6-postgis-2.3
Just before tables creation add:
db.engine.execute('create extension postgis')
db.create_all()
This has already been answered but I wanted to add a more thorough answer that explains why certain commands work, and in what circumstances to use them, and of course, how to figure out which circumstances you are in.
First, you need to check that PostGIS is actually installed on your box. When connected to postgres, such as via psql, run:
SELECT PostGIS_Full_Version();
If it's not installed, look up distro- and version-specific instructions for installing PostGIS and install it.
Assuming PostGIS is installed, the error is usually the result of not having "created" (this is an unfortunately misleading use of language, the effect is more like "enabling" the extension) the extension for the particular database. The way PostgreSQL is set up, by default new databases do not come with any extensions enabled, and you need to enable ("create") them per-database. In order to do this you need to run the following command.
It only needs to be run once:
CREATE EXTENSION postgis;
I think you need superuser privileges for the particular database in question, in order to run this command.
Assuming postgres is configured so that the permissions allow, you can execute this command from the command line by running the following command:
psql my_database -c "CREATE EXTENSION postgis;"
You may need to use the -U flag and specify a user.
In some cases, however, the extension may have already been created, and installed under a different schema than public, and the problem may be one of permissions. This can arise like in the situation #mozboz describes, if you create a new user but don't give it access to the schema. To detect this case, look for a separate schema in the database, with a table called spatial_ref_sys, as this is created when the extension is created.
In this case you may need to run, when connected to the database:
GRANT USAGE ON SCHEMA schema_name TO username;
In my experience, this situation is rare, and I have never found any reason to set things up this way. The schema_name is often, but not always postgis. By default if you run the first command here, it will create the extension under the public schema.
I think USAGE is usually sufficient for most cases, but you might want to grant more privileges if you want the user to be able to actually edit data; the only time this has ever come up for me was adding new projections to spatial_ref_system, but even this is rare as by default that table includes most commonly used projections.
Or...
cursor.execute('create extension postgis')
in your python program, using a current cursor from psycopg2.
My experience was I was trying to load the ism file to a different file than "public". I initialised the postgis extension on another schema other than public. So that didn't work. So finally I had to remove the extension, and than created the postgis extension in public. After that I could load the osm into my new schema
Osm always looks for the extension file in public, irregardless of where u intend to install the osm files in another schema
Verify the public search_path is not included for the user:
SELECT usename, useconfig from pg_user;
-- { search_path=pg_catalog, public }
SHOW SEARCH_PATH;
-- public, topology
Method #1: SET the search_path to public
SET search_path = "public";
CREATE TABLE IF NOT EXISTS sample_geom
(
geom_1 GEOMETRY,
geom_2 GEOMETRY(Polygon, 4326) NOT NULL
);
ALTER TABLE sample_geom
OWNER TO root;
Method #2: Use the qualified object name for the GEOMETRY object type (public.GEOMETRY)
CREATE TABLE IF NOT EXISTS sample_geom
(
geom_1 public.GEOMETRY,
geom_2 public.GEOMETRY(Polygon, 4326) NOT NULL
);
ALTER TABLE sample_geom
OWNER TO root;
Source: Demystifying Schemas & search_path through Examples
Using pgAdmin 4,you can sort this:
Click on the SQL query button (or go to Tools >
Query Tool).
Enter the following query into the query text field to load the PostGIS spatial extension and Click the Play button in the toolbar (or press F5) to “Execute the query.”
CREATE EXTENSION postgis;
Succesful feedback
Now confirm that PostGIS is installed by running a PostGIS function:
SELECT postgis_full_version();
Code
Feedback