Skip to content

docs+test: skip_duplicates enforces secondary unique constraints on PostgreSQL (fixes #1049)#1417

Open
dimitri-yatsenko wants to merge 1 commit intomasterfrom
fix/1049-skip-duplicates-unique-postgres
Open

docs+test: skip_duplicates enforces secondary unique constraints on PostgreSQL (fixes #1049)#1417
dimitri-yatsenko wants to merge 1 commit intomasterfrom
fix/1049-skip-duplicates-unique-postgres

Conversation

@dimitri-yatsenko
Copy link
Copy Markdown
Member

Summary

Resolves #1049.

No new skip_duplicates modes are needed. PostgreSQL already enforces secondary unique constraints when skip_duplicates=True, because the generated SQL targets only the primary key:

-- PostgreSQL: ON CONFLICT (pk) DO NOTHING
-- PK duplicates silently skipped
-- secondary unique violations still raise DuplicateError

This PR documents the behavior and adds integration tests proving it works.

Backend difference (documented, not changed)

Scenario MySQL PostgreSQL
PK duplicate skip skip
Secondary unique conflict (different PK) skip silently raises DuplicateError

MySQL's ON DUPLICATE KEY UPDATE catches all unique key conflicts. This is a known asymmetry documented in the updated insert() docstring.

Changes

  • table.py: Updated skip_duplicates docstring to explain the PostgreSQL vs MySQL difference.
  • test_skip_duplicates.py: New integration test file with 6 tests (x 2 backends = 12 runs, 4 backend-specific skips):
    • test_skip_duplicates_pk_match -- PK dup silently skipped (both backends)
    • test_skip_duplicates_unique_violation_raises_on_postgres -- new PK + conflicting unique raises (PG only)
    • test_skip_duplicates_unique_on_mysql -- documents MySQL silent skip behavior
    • test_skip_duplicates_no_unique_index -- works normally without secondary indexes
    • test_skip_duplicates_composite_unique -- composite unique index enforced (PG only)
    • test_skip_duplicates_batch_mixed -- batch with PK dups + unique conflict (PG only)

Test plan

  • All 12 test runs pass (8 passed, 4 skipped by backend)
  • Full suite: 797 passed, 9 skipped

Generated with Claude Code

…nstraints

Resolves #1049 — on PostgreSQL, skip_duplicates=True already enforces
secondary unique constraints (ON CONFLICT (pk) DO NOTHING targets only
the primary key). On MySQL, ON DUPLICATE KEY UPDATE catches all unique
keys, silently skipping secondary violations too.

Changes:
- Update insert() docstring to document the backend difference.
- Add integration tests covering: PK-only skip, secondary unique
  violation on PostgreSQL (raises), MySQL silent skip (documented
  asymmetry), composite unique indexes, batch inserts with mixed
  duplicates, and tables without secondary unique indexes.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
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.

Advanced handling of duplicates in insert1

1 participant