ilyakatz / data-migrate

Migrate and update data alongside your database structure.
MIT License
1.42k stars 194 forks source link

Issue with RLS - the migrations themselves work but inserting into the metadata fails #257

Open ericgross opened 1 year ago

ericgross commented 1 year ago

I have a data migration which uses RLS.run_per_tenant in order to handle the tenant_id, and it seems to work fine. I am currently having an issue though where the DataMigrate::DataSchemaMigration insertion seems to be happening outside of my ability to handle RLS.

Now that I think about it, I think what would be ideal here would be to track which tenants have had which data migrations run against them - is that possible? If not, is it possible to track which data migrations have been run on the database as normal? I think this would require running RLS.disable! somewhere.

IGNORE_NO_TENANTS=true rails db:migrate:with_data
Accessing database as Marina 1
== Data =======================================================================
== 20230602202919 AddRoles: migrating =========================================
WARNING: ROW LEVEL SECURITY DISABLED!
Accessing database as Marina 1
Accessing database as Marina 2
Accessing database as Marina 3
== 20230602202919 AddRoles: migrated (0.0563s) ================================

rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::RaiseException: ERROR:  RLS not set up!
HINT:  Please set rls.tenant_id or set rls.disable to FALSE.
CONTEXT:  PL/pgSQL function rls_disabled() line 5 at RAISE

Caused by:
ActiveRecord::StatementInvalid: PG::RaiseException: ERROR:  RLS not set up!
HINT:  Please set rls.tenant_id or set rls.disable to FALSE.
CONTEXT:  PL/pgSQL function rls_disabled() line 5 at RAISE

Caused by:
PG::RaiseException: ERROR:  RLS not set up!
HINT:  Please set rls.tenant_id or set rls.disable to FALSE.
CONTEXT:  PL/pgSQL function rls_disabled() line 5 at RAISE

Tasks: TOP => db:migrate:with_data
(See full trace by running task with --trace)
ilyakatz commented 1 year ago

Hi @ericgross thanks for the issue/suggestion. RLS is not something that I configured in the gem explicitly. The easy way out would be to disable RLS in your migration file and reenable it at the end. As far as tracking tenants, that can potentially be done since there is a "schema" file for data migration and it could be dumped there, but I can see there being problems with test/production separation. Would you be interested in contributing something? (TBH, i haven't dealt with rails in really long time but maintaining the gem since it's used a lot)

ericgross commented 1 year ago

The easy way out would be to disable RLS in your migration file and reenable it at the end.

I haven't figured out a way to disable RLS in such a way that is active when the version is being inserted into the database - any idea how I could do that?

As far as tracking tenants, that can potentially be done since there is a "schema" file for data migration and it could be dumped there, but I can see there being problems with test/production separation.

I am fine with a situation where data-migrate tracks things on a per-database basis rather than dealing with per-tenant anything - if I need per-tenant data migrations, I can build that ... but I hope to avoid it.

Would you be interested in contributing something?

Yes, I would be up for that! I would want to make sure anything I do is in-line with your thoughts first though.