Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make add_foreign_key retriable when safe_by_default is enabled #273

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

chaadow
Copy link
Contributor

@chaadow chaadow commented Sep 1, 2024

related to #272 and #271

When adding a foreign key and safe mode is enabled:

  • We create a NOT VALID foreign key
  • Then we commit the transaction
  • Finally we validate the foreign key constraint

if the validation fails, this leaves a NOT VALID foreign key in the database.
If we retry after having cleaned up the database, the creation of the NOT VALID foreign key constraint will fail because it will already be in the DB.

This commit makes the migration safely retriable by checking if said foreign key constraint already exists, and if so, skips its creation again.

When validation of foreign key fails, we also remove the NOT VALID foreign key constraint as to not leave the database in an unstable state.

@migration.reversible do |dir|
dir.up do
@migration.add_foreign_key(from_table, to_table, *args, **options.merge(validate: false))
# https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb#L1154C96-L1154C120
# if_not_exists does not check again `name` option.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until a fix is done/merged on Rails, I believe we still need to leave this.

This was detected by AddForeignKeyName test class, as it creates 2 foreign keys on the same column but with different names ( It's quite rare I think for users of this gem to encounter this case but nonetheless, it's more robust and makes tests pass )

When adding a foreign key and safe mode is enabled:
- We create a NOT VALID foreign key
- Then we commit the transaction
- Finally we validate the foreign key constraint

if the validation fails, this leaves a NOT VALID foreign key in the
database.
If we retry after having cleaned up the database, the creation of the
NOT VALID foreign key constraint will fail because it will already
be in the DB.

This commit makes the migration safely retriable by checking
if said foreign key constraint already exists, and if so,
skips its creation again.

When validation of foreign key fails, we also remove the NOT VALID
foreign key constraint as to not leave the database in an unstable
state.
@chaadow chaadow force-pushed the fix_safe_default_add_foreign_key branch from e5f9621 to f7e12e8 Compare September 1, 2024 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant