Reset PK sequences after mounting cached fixtures (#51)#58
Merged
Conversation
ActiveRecordCoder#mount replays INSERTs that include explicit primary key values. Postgres sequences don't observe these inserts, so a later Model.create can call nextval and collide with an id we just inserted — intermittent PG::UniqueViolation in test runs that mount the cache onto a database whose sequence is at its initial value (e.g. parallel test workers with their own DB copies). Reset the sequence per connection after the batch executes: - Prefer connection.reset_column_sequences! when available (Rails main / 8.2+) — batches the reset in one round-trip per connection - Fall back to per-table connection.reset_pk_sequence! (Rails 8.0/8.1) - Skip silently on adapters that expose neither (MySQL, SQLite) Adds spec/integration/pk_sequence_repro_spec.rb that simulates the parallel-worker scenario by wiping the table and resetting the PK generator after the auto-mount, then re-mounting and asserting that a fresh Model.create succeeds. Without the fix this fails on Postgres with PG::UniqueViolation; passes naturally on MySQL/SQLite. Closes #51 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #51
Summary
ActiveRecordCoder#mountreplays INSERTs that include explicit primary key values. Postgres sequences don't observe these inserts, so a laterModel.createcallsnextvaland collides with an id we just inserted. IntermittentPG::UniqueViolationin test runs that mount the cache onto a database whose sequence is at its initial value (e.g. parallel test workers with their own DB copies).Fix
Reset the sequence per connection after the batch executes:
connection.reset_column_sequences!(Rails main / 8.2+) — batches the reset in one round-trip per connectionconnection.reset_pk_sequence!(Rails 8.0/8.1)Repro spec
spec/integration/pk_sequence_repro_spec.rbsimulates the parallel-worker scenario by wiping the table and resetting the PK generator after the auto-mount, then re-mounting and asserting that a freshModel.createsucceeds.Without the fix this fails on Postgres with
PG::UniqueViolation: duplicate key value violates unique constraint "users_pkey", Key (id)=(1) already exists. Passes naturally on MySQL and SQLite.Why batched + fallback
The batched method (rails/rails#55928) was added to address per-table sequence reset being slow on large schemas. Using it when available means fixture_kit users on Rails 8.2+ get the perf win automatically. The per-table fallback covers our currently-supported 8.0 and 8.1.
Stack
Last in the stack — sits on #57 (which adds the PG matrix that exercises this fix in CI).
Test plan
🤖 Generated with Claude Code