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

Fix error when seeding in AWS non-production #1400

Merged
merged 4 commits into from
Oct 10, 2024
Merged

Conversation

Cruikshanks
Copy link
Member

@Cruikshanks Cruikshanks commented Oct 10, 2024

Unlike migrations, which are only expected to be run once against a DB, seeders may be run repeatedly. For example, a new charge version, 'change reason', is required in the future. We would add it to our db/seeds/data/change-reasons.js and re-run npm run seed.

Because of this, each seeder needs to be able to handle being run against an environment where the records may already exist.

In most cases, we can exploit constraints in the DB and PostgreSQL's ON CONFLICT clause, also known as an 'upsert'.

We try to insert a record, but when a conflict error is thrown because a matching record already exists, we can instruct PostgreSQL to update certain fields instead.

That is unless it is idm.users! The previous team appear to have opted instead to create their own custom sequence and use a number as the ID. 😩

Instead of the expected on conflict being raised, we're getting a primary key violation. The simplest solution is to check if a record exists first. We can then determine if we need to insert our user record or update an existing one.

If we are updating, we must then check if the seed ID we want to use is already in use. If it is, we have to drop ID from our insert statement and let the custom sequence assign us one instead.

Unlike migrations, which are only ever expected to be run once against a DB, seeders may be run repeatedly. For example, a new charge version 'change reason' is required in the future. We would add it to our `db/seeds/data/change-reasons.js` and simply
re-run `npm run seed`.

Because of this each seeder needs to be able to handle being run against an environment where the records may already exist.

In most cases, we can exploit constraints in the DB and PostgreSQL's [ON CONFLICT clause](https://www.postgresql.org/docs/current/sql-insert.html), also known as an 'upsert'.

We try to insert a record, but when a conflict error is thrown because a matching record already exists, we can instruct PostgreSQL to update certain fields instead.

That is unless it is `idm.users`! The previous team appear to have opted instead to create their own custom sequence and use a number as the ID. 😩

Instead of the expected `on conflict` being raised, we're getting a primary key violation. Simplest solution is to fall back to checking if a record exists first, and then running the insert or update separately depending on the result.
@Cruikshanks Cruikshanks added the bug Something isn't working label Oct 10, 2024
@Cruikshanks Cruikshanks self-assigned this Oct 10, 2024
@Cruikshanks Cruikshanks marked this pull request as ready for review October 10, 2024 13:42
@Cruikshanks Cruikshanks merged commit f710548 into main Oct 10, 2024
6 checks passed
@Cruikshanks Cruikshanks deleted the fix-users-seeding branch October 10, 2024 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant