FlywayDB not creating extension - postgresql

I have this startup script which is picked up by FlywayDB:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- clean up
DROP table IF EXISTS tenants;
-- create table
CREATE TABLE tenants (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name VARCHAR(64) NOT NULL
);
and my spring boot config:
#FLYWAY
spring.flyway.url=jdbc:postgresql://localhost:5432/tenant?currentSchema=public
spring.flyway.user=postgres
spring.flyway.password=secret
spring.flyway.baseline-on-migrate=true
All my scripts are working fine except for "CREATE EXTENTION" bit.
I can log in the DB with the same credentials and run it manually with success. But via FlyWay: No Way. Wonder why

This should work just fine and is widely used. Make sure your user has the necessary permissions to do so.

Loading an extension requires the same privileges that would be
required to create its component objects. For most extensions this
means superuser or database owner privileges are needed. The user who
runs CREATE EXTENSION becomes the owner of the extension for purposes
of later privilege checks, as well as the owner of any objects created
by the extension's script.
read docs: CREATE EXTENSION

Related

Adonis and PostgreSQL: create table "adonis_schema"... fails with 'permission denied for schema public'

I have been following the dockerizing-adonis tutorial which uses PostgreSQL as database.
I am new to Postgres and do not completely understand its user/role/schema concepts yet.
In the tutorial pretty early on I'm instructed to create dockerConfig/postgres-dev-init.sql with this content:
CREATE USER adonis with encrypted password 'adonis';
CREATE DATABASE adonis_app;
GRANT ALL PRIVILEGES ON DATABASE adonis_app TO adonis;
Then further down in the docker-compse.yml there is
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
I followed the tutorial and also updated the .env file - the tutorial works - but does not use the database.
So I created a model with a migration: node ace make:model User -m
now I want to run that migration to create the User table.
Running node ace migration:run gets me the error
[ error ] create table "adonis_schema" ("id" serial primary key,
"name" varchar(255) not null, "batch" integer not null,
"migration_time" timestamptz default CURRENT_TIMESTAMP) - permission
denied for schema public
I want this setup with 2 users (postgres as the root user, adonis to be used by adonis) to work the way its suggested in the tutorial and understand postgre better (later i want to add a grafana user with just read-access).
Why is the permission denied? Does the init .sql file need more instructions? Shouldn't the user adonis by default already have the required create rights on the public schema, or am I misunderstanding that concept of the public schema in postgres?
Am I somehow completely on the wrong track, or should the tutorial somehow make this work and misses something (In which case I would create an issue for the adonis doc ...)?
Tutorial should work. I use it myself :)
I believe you skipped this part of docs:

Create foreign table on file_fdw as non-superuser

I have created a file_fdw extension and a corresponding server as superuser.
CREATE EXTENSION file_fdw;
CREATE SERVER myserver FOREIGN DATA WRAPPER file_fdw;
ALTER SERVER myserver OWNER TO nonsuperuser;
I want a non-superuser nonsuperuser to use this server to create a foreign table
CREATE FOREIGN TABLE test (
a text NULL,
b text NULL
)
SERVER myserver
OPTIONS (filename '/home/me/mycsvfile.csv', format 'csv', header 'true', delimiter ';');
Executing this, leads to `only superuser can change options of a file_fdw foreign table
What can I do to enable nonsuperuser to create foreign tables? If possible I would not mind declaring the options as super user.
Only highly privileged users are allowed to access files on the database server, that's why you need high permissions to create a file_fdw foreign table.
From the error message it becomes clear that you are using an old version of PostgreSQL; on more recent versions, the error message would look like:
only superuser or a member of the pg_read_server_files role may specify the filename option of a file_fdw foreign table
So, as an alternative to dealing out superuser privileges, you may add the user to the pg_read_server_files role.
Upgrade PostgreSQL!

PostgreSql hstore extension with public prefix issue

I've struggled with my PostgreSql and hstore extension, so in my sql dump file hstore fields are created with this script:
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
CREATE TABLE public.identity_devices (
...
metadata public.hstore
);
So I'm getting an error
structure.sql:2058: ERROR: type "public.hstore" does not exist
But in case I use
metadata hstore
everything works fine.
Also, have to note that this happens only on our CI where we're running as user runner but owner of public schema is postgres.
If needs some more data, please let me know and I will provide.
Regards,
You can check if and where the extension is already installed using the command \dx hstore
As we're using Postgres9.3 we have to install hstore manually, on our CI they use Postgres9.6 which automatically add hstore on Db creation.
Also, it puts hstore in namespace pg_catalog which turned out was the main reason why hstore wasn't visible by public.hstore.
So what I had to do is to do one step after creating db on CI, which drop particular extension and creates new one in correct schema.
Anyway, the problem wasn't so hard as it was tricky and weird.

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.

Install extension in PostgreSQL database via migration without superuser role?

We are using migrations (via Sequelize, in JavaScript) to maintain changes to our database. I have a need to add a CREATE EXTENSION call but since I am running as the database creator, and not superuser, I get a permission denied to create extension.
Is there a way to modify security on a single database to allow a user to install an extension via a migration file? IOW, when I create the "naked" database and apply my permissions, can I set security up to allow CREATE EXTENSION and DROP EXTENSION for a specific user?
No, there is no setting for CREATE ROLE for granular CREATE/DROP EXTENSION control. I assume, it depends on the extension you use, but you based on the documentation:
Loading an extension requires the same privileges that would be
required to create its component objects. For most extensions this
means superuser or database owner privileges are needed. The user who
runs CREATE EXTENSION becomes the owner of the extension for purposes
of later privilege checks, as well as the owner of any objects created
by the extension's script.
I was running into the same issue with pg_trgm extension, but even setting role to database owner did not resolve the issue.
Could not find a way to do this inside a migration file.
The technique we ended up using was to have a subfolder in the migration folder, called postgres to hold anything that must be run as superuser. The subfolder contained the migrations and a config file for running things as a superuser. So, the command-line becomes:
$ sequelize db:migrate --migrations-path "migrations/postgres" --config "migrations/postgres"
$ sequelize db:migrate
The inconvenience of a more complex command-line was mitigated by the fact that the "special" migrations that required this isolation also made them more evident.
For anyone still looking, here is how to create an extension via a sequelize migration. It doesn't address the secondary question of user roles however. But this works for me.
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query('CREATE EXTENSION extensionName;');
},
down: (queryInterface, Sequelize) => {
return queryInterface.sequelize.query('DROP EXTENSION extensionName;');
}
};