cli icon indicating copy to clipboard operation
cli copied to clipboard

Migration file mistake when changing primary key column from int to uuid with gen_random_uuid() as default

Open gc-ft opened this issue 1 year ago • 0 comments

Describe the bug The migration scripts generated by supabase db pull when a column was changed from an initial int primary key to a uuid primary key will build a set of migrations with this logic:

  1. change default value of column to gen_random_uuid()
  2. drop identity from column
  3. change the data type to uuid using id::uuid casting.

This will surely fail, even for a fully empty fresh database, because 1) can not be done before 2).

To Reproduce Steps to reproduce the behavior:

  1. Create a default supabase table in the dashboard
  2. Alter the supabase table primary key to uuid in the dashboard using gen_random_uuid() as default
  3. Build a migration script using supabase db pull
  4. Try to pull one more time after this, making the migration system build a temporary db
  5. Error:
ERROR: column "id" of relation "relation" is an identity column (SQLSTATE 42601)                
At statement 93: alter table "public"."relation" alter column "id" set default gen_random_uuid()

Expected behavior Migration process that makes sense should be:

  1. drop identity from column
  2. change the data type to uuid using gen_random_uuid()
  3. change default value of column to gen_random_uuid()

Additional thoughts I can very well understand if you say the "error" behaviour is better, considering that:

  1. It seems bad design and usage to change a primary key from int to uuid at some point late in the process
  2. Most importantly because foreign key issues and the like will most likely occur when changing from int to uuid as it is not a trivial change.

However, in initial db design and needed migrations for that, while still developing, it seems better to use the above approach in order to migrate the db column than erroring out.

I do not have enough experience with postgreSQL foreign key setups to know if alter table ... using gen_random_uuid() might even with a production db work if the foreign keys allow for cascading updates, however I doubt they will since the foreign key targets will need to have their column types altered before anyway... therefor, more complex migration would then be needed I guess which first removes the foreign keys and reads them once the columns are updated?

gc-ft avatar Aug 09 '24 11:08 gc-ft