Search code examples
postgresqltypeorm

does set search_path of postgres affect connection or the database


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;

Solution

  • 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 ...