Test duplicate enqueue behavior with a temporary SQLite database

Direct answer

A queue deduplication rule belongs in the database when more than one caller can attempt the same insert. This example gives dedupe_key a UNIQUE constraint, performs the first enqueue, and treats sqlite3.IntegrityError from the second insert as an expected outcome. The count assertion is important: it checks that the failure did not silently create a second job.

A temporary file is preferable to a production queue for this test because it exercises SQLite’s on-disk constraint handling without preserving a fixture. The result is not an invitation to catch every integrity error and continue. A foreign-key failure and a duplicate key have different operational meanings; identify the constraint or use a dedicated insert statement before declaring an enqueue idempotent.

This code covers sequential duplicate inserts. It does not define a retry schedule, select a conflict policy such as INSERT OR IGNORE, or test competing processes. If callers need to recover an existing job identifier, query it deliberately after the duplicate result and test that lookup under the same transaction rules.

Complete example

import sqlite3
from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as directory:
    connection = sqlite3.connect(Path(directory) / "queue.sqlite3")
    connection.execute("CREATE TABLE jobs (dedupe_key TEXT UNIQUE)")
    connection.execute("INSERT INTO jobs VALUES ('daily-summary')")
    connection.commit()
    try:
        connection.execute("INSERT INTO jobs VALUES ('daily-summary')")
    except sqlite3.IntegrityError:
        outcome = "duplicate-rejected"
    else:
        raise AssertionError("duplicate enqueue succeeded")
    assert connection.execute("SELECT COUNT(*) FROM jobs").fetchone()[0] == 1
    print(outcome)
    connection.close()

Expected stdout:

duplicate-rejected

Sources

- sqlite3 documentation

- SQLite transaction documentation

Prepared with AI assistance. The example uses synthetic data; its stated limits apply.

Comments

Popular posts from this blog

Compare Two Text Files in Python Without Modifying Them

Seven CSV Quality Checks to Run Before Importing Data

Explain why SQLite transactions cannot make an HTTP call atomic