Skip to content

Add `id` as primary key for project framework settings table

Hitesh Raghuvanshi requested to merge 420976-migration-multiple-frameworks into master

What does this MR do and why?

We are adding support for multiple compliance framework labels for a project. Currently only one compliance framework label is allowed per project.

  1. project_compliance_framework_settings table stores mapping of project and compliance framework associated with it.
  2. This table does not have any id column and the primary key is project_id which means project is a unique field. To support multiple frameworks for a project, we need to add id column as primary key and remove unique constraint from project_id column as there could be multiple entries for a project.
  3. But we need to make sure that the combination of a project and a framework should be unique, so we need to add a unique constraint on these two fields.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Database

Migration for changing primary key


### up

bundle exec rake db:migrate:up:main VERSION=20240528060203
main: == [advisory_lock_connection] object_id: 123920, pg_backend_pid: 12136
main: == 20240528060203 ChangePrimaryKeyOfProjectComplianceFrameworkSettings: migrating 
main: -- execute("ALTER TABLE project_compliance_framework_settings DROP CONSTRAINT IF EXISTS project_compliance_framework_settings_pkey\n")
main:    -> 0.0020s
main: -- add_column(:project_compliance_framework_settings, :id, :primary_key, {:if_not_exists=>true})
main:    -> 0.0255s
main: == 20240528060203 ChangePrimaryKeyOfProjectComplianceFrameworkSettings: migrated (0.0314s) 

main: == [advisory_lock_connection] object_id: 123920, pg_backend_pid: 12136

### down

 bundle exec rake db:migrate:down:main VERSION=20240528060203              
main: == [advisory_lock_connection] object_id: 123920, pg_backend_pid: 11460
main: == 20240528060203 ChangePrimaryKeyOfProjectComplianceFrameworkSettings: reverting 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- remove_column(:project_compliance_framework_settings, :id, {:if_exists=>true})
main:    -> 0.0238s
main: -- execute("ALTER TABLE project_compliance_framework_settings ADD PRIMARY KEY (project_id)\n")
main:    -> 0.0019s
main: == 20240528060203 ChangePrimaryKeyOfProjectComplianceFrameworkSettings: reverted (0.0525s) 

main: == [advisory_lock_connection] object_id: 123920, pg_backend_pid: 11460

Migration for adding unique constraint


### up

bundle exec rake db:migrate:up:main VERSION=20240528055716
main: == [advisory_lock_connection] object_id: 124140, pg_backend_pid: 8890
main: == 20240528055716 AddUniqueIndexToProjectFrameworkSettingsOnProjectFrameworkId: migrating 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0207s
main: -- indexes(:project_compliance_framework_settings)
main:    -> 0.0030s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0001s
main: -- remove_index(:project_compliance_framework_settings, {:algorithm=>:concurrently, :name=>"index_project_compliance_framework_settings_on_project_id"})
main:    -> 0.0016s
main: -- execute("RESET statement_timeout")
main:    -> 0.0002s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0007s
main: -- index_exists?(:project_compliance_framework_settings, [:project_id, :framework_id], {:unique=>true, :name=>"uniq_idx_project_compliance_framework_on_project_framework", :algorithm=>:concurrently})
main:    -> 0.0012s
main: -- add_index(:project_compliance_framework_settings, [:project_id, :framework_id], {:unique=>true, :name=>"uniq_idx_project_compliance_framework_on_project_framework", :algorithm=>:concurrently})
main:    -> 0.0020s
main: == 20240528055716 AddUniqueIndexToProjectFrameworkSettingsOnProjectFrameworkId: migrated (0.0473s) 

main: == [advisory_lock_connection] object_id: 124140, pg_backend_pid: 8890


### down

bundle exec rake db:migrate:down:main VERSION=20240528055716              
main: == [advisory_lock_connection] object_id: 125720, pg_backend_pid: 8163
main: == 20240528055716 AddUniqueIndexToProjectFrameworkSettingsOnProjectFrameworkId: reverting 
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0211s
main: -- indexes(:project_compliance_framework_settings)
main:    -> 0.0051s
main: -- execute("SET statement_timeout TO 0")
main:    -> 0.0002s
main: -- remove_index(:project_compliance_framework_settings, {:algorithm=>:concurrently, :name=>"uniq_idx_project_compliance_framework_on_project_framework"})
main:    -> 0.0025s
main: -- execute("RESET statement_timeout")
main:    -> 0.0002s
main: -- transaction_open?(nil)
main:    -> 0.0000s
main: -- view_exists?(:postgres_partitions)
main:    -> 0.0005s
main: -- index_exists?(:project_compliance_framework_settings, :project_id, {:name=>"index_project_compliance_framework_settings_on_project_id", :algorithm=>:concurrently})
main:    -> 0.0020s
main: -- add_index(:project_compliance_framework_settings, :project_id, {:name=>"index_project_compliance_framework_settings_on_project_id", :algorithm=>:concurrently})
main:    -> 0.0031s
main: == 20240528055716 AddUniqueIndexToProjectFrameworkSettingsOnProjectFrameworkId: reverted (0.0670s) 

main: == [advisory_lock_connection] object_id: 125720, pg_backend_pid: 8163

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

Related to #464156 (closed)

Edited by Hitesh Raghuvanshi

Merge request reports