Typeorm's migration is quite unexpected, even though I specify the schema, migrations run though the queryRunner, don't respect the schema specified in the connection:
const dbconfig: DataSourceOptions = {
...baseConnection,
schema: my_schema,
migrations: ['./**/*.migration.js'],
};
let data = new DataSource(dbconfig);
data = await data.initialize();
data.runMigrations()
it only seems to work if you've used something like a repository, orm specific.
One way I got around this is by using a static variable that persists throughout the migration process the name of the schema, and sets search_path of the database before each query, like this:
set search_path to ${static_variable.my_schema};
run_query_1;
set search_path to ${static_variable.my_schema};
run_query_2;
...
set search_path to ${static_variable.my_schema};
run_query_n;
Consider this case,(1) an admin starts a migration, the schema is set to 'X', the database search_path is set to 'X', in the midst of this process, if a request comes in from tenant 'Y', then would he be writing to the tenant 'X' or 'Y'
(2) If the app is horizontally scaled, then if two admins are performing migrations for two tenants, (there are two different static vars now), how would this affect the authenticity and integrity of the data.
If the set search_path is connection specifically maintained, then I suppose it could matter less , but if the database globally manages it, this could be an issue.
Are these concurrent operations going to be a problem? Should I opt to modify the search_path at all?
EDIT: What about for the case like this:
START TRANSACTION;
set search_path to ${static_variable.my_schema};
run_query_1;
set search_path to ${static_variable.my_schema};
run_query_2;
...
set search_path to ${static_variable.my_schema};
run_query_n;
COMMIT;
As documented in the manual SET changes the setting for the session (or just the transaction if the local keyword is included).
So if you always use set search_patt to ... it's always specific to the connection (session) that executed the statement. You will not have a concurrency issue.
There is one way this could have an effect globally: if you change the search path in the database using alter database set search_path ... or for the user using alter user set search_path ...
Related
A script has to import SQL data into an PostgreSQL database. The SQL includes these two lines of code:
SET session_replication_role = 'replica';
...
SET session_replication_role = 'origin';
The user xyz who starts the import doesn't have the power to do this yet. The error PG::InsufficientPrivilege gets displayed.
How (with which SQL query) can the user postgres grant the user xyz the right to set session_replication_role? I can't find any documentation about that.
As of PostgreSQL 15+ there is a way to do this:
GRANT SET ON PARAMETER session_replication_role TO xyz;
https://www.postgresql.org/docs/15/sql-grant.html
I haven't tried this yet but I bet it works good - in version 14, I used SECURITY DEFINER at the end of a plpgsql procedure with "SET session_replication_role" statements inside of it, and made sure a superuser account was the definer/owner of the procedure - then, any user with EXECUTE privilege can still run it and the parameter setting works as you would hope.
It is impossible :-(. See:
It seems this is currently only possible with superuser privilege:
Setting this variable requires superuser privilege, cf.
postgresql.org/docs/current/runtime-config-client.html
I have a Postgres database in Cloud SQL and would like to utilize the pg_trgm extension to do similarity searches. However, the default threshold parameters are not sensitive enough in my use case so they should be altered.
The problem is that Cloud SQL does not provide database flags for either pg_trgm.similarity_threshold or pg_trgm.word_similarity_threshold and the database users do not have the privileges to alter the user or database:
postgres=> ALTER ROLE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
postgres=> ALTER DATABASE postgres SET pg_trgm.similarity_threshold = 0.1;
ERROR: permission denied to set parameter "pg_trgm.similarity_threshold"
Is there any other way to alter these parameters?
Can you do the straightforward SET pg_trgm.similarity_threshold = 0.1;? You would have to repeat it in every session, so maybe incorporate it into your connection sub.
For similarity_threshold, you can use the function set_limit unless Google has also disabled that. You would also have to set it this way in each session, though. There is no alternative way to set word_similarity_threshold, though, unless Google has invented one.
Encountered this issue when trying to modify the search_path to my new Redshift db.
Presently, I've migrated the contents of my MySQL db into a redshift cluster via AWS' Data Migration Service. The data was imported into a schema lets call my_schema. When I try to execute queries against the cluster it requires me to prefix table names with the schema name
i.e.
select * from my_schema.my_table
I wanted to change the setup so that I can reference the table directly without needing the prefix. After a bit of looking around I found out that this was possible by modifying the search_path attribute.
First I tried doing this by running
set search_path = "$user", my_schema;
This appeared to work but then I realized that this was simply setting my_schema as the default schema in the context of the current session, I wanted it set on a database level. I found several sources saying that the way to do this was to use the alter command like so...
alter database my_db set search_path = "$user", public, my_schema
However, running this command results in the following error which somehow shows up in 0 google results:
SET/RESET commmand in ALTER DATABASE is not supported
I'm pretty baffled by how the above error hasn't ever had a post made about it but I'm also pretty interested in figuring out how to resolve my initial issue of setting a global default schema for my redshift cluster.
ALTER DATABASE SET is not supported in Redshift. However you can SET/RESET configuration parameters at USER level using the ALTER USER SET SEARCH_PATH TO <SCHEMA1>,<SCHMEA2>;
Please check: http://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_USER.html
http://docs.aws.amazon.com/redshift/latest/dg/r_search_path.html
When you set the search_path to <SCHEMA1>,<SCHMEA2> in db1 for a user it is not for just current session, it will be set for all future sessions.
My Postgres database is a multi-schema one.
Each schema got the same structures but the data are differents.
It was working fine since i encountered a specific problem.
It seems that views are generated based on the current search_path.
Let's say my database is like :
public
schema1
If i SET search_path TO schema1, public.
Then SELECT * FROM schema1.view;
It will retrieve the data from the public schema.
I tried to change the search_path before generating my view, it didn't work.
I tried to prefix my tables into my view, it worked. My solution is to prefix with the target schema before creating my views with my 'new database' script. But i find it a bit 'dirty';
I'd love to have more insight on the subject !
Thanks
When a view is created, all unqualified object names in the view definition are resolved according to the value of search_path at the time the view is created. The Object-ID of the referenced tables is part of the view definition.
So it does not matter what search_path is set to when you SELECT from the view.
I already know how to set the search_path per database or user (alter database set search_path to schema1, schema2, ...).
What I would like to do is append a schema to the default search path. I know I can get the current search path (show search_path) but this could have been altered during the session.
The purpose is something like:
create schema postgis;
set search_path to postgis;
create extension postgis;
alter database the_db set search_path to <the current default>, postgis;
I can do this manually but I want to add this to a function that could be called after the user altered the session search path.
Ah, found it.
For my purposes I can just do
set search_path to default;
before appending.
This updates search_path for current session & also future sessions. base on these two posts
DO $$
BEGIN
execute 'alter database '||current_database()||' set search_path to '||current_setting('search_path')||',extensions';
execute 'set search_path to '||current_setting('search_path')||',extensions';
END
$$;