Skip to content

Ability to define unique columns when creating a table - #898

Open
sqmyou wants to merge 1 commit into
simonw:mainfrom
sqmyou:unique-columns-create-558
Open

sqmyou wants to merge 1 commit into
simonw:mainfrom
sqmyou:unique-columns-create-558

Conversation

@sqmyou

@sqmyou sqmyou commented Oct 7, 2026 •

Copy link
Copy Markdown

Refs #558.

Summary

Adds a unique= argument for defining UNIQUE constraints when a table is created, mirroring the existing not_null= argument.

db["ExampleTable"].create(
    {"mRID": str, "name": str},
    pk="mRID",
    unique=["mRID"],
    if_not_exists=True,
)

A string names a single column; a tuple names a compound constraint spanning several columns. Both can be combined in one list:

db.table("memberships").create(
    {"account_id": int, "email": str, "role": str},
    unique=["role", ("account_id", "email")],
)

Produces:

CREATE TABLE "memberships" (
   "account_id" INTEGER,
   "email" TEXT,
   "role" TEXT,
   UNIQUE ("role"),
   UNIQUE ("account_id", "email")
)

Where it is accepted

  • Database.create_table()
  • Table.create()
  • Table.transform() - adds the constraint to an existing table; repeating a constraint that is already present is a no-op
  • The table-creating methods insert(), insert_all(), upsert() and upsert_all()
  • As a table default via db.table(..., unique=[...])

create(..., transform=True) detects a newly requested constraint and applies it.

Also added

  • A table.uniques introspection property listing the UNIQUE constraints on a table, mirroring table.checks.
  • Documentation for the new argument and property in docs/python-api.rst.

Tests

16 new tests in tests/test_create.py cover single-column, multi-column and compound constraints, constraint enforcement, the bad-column error, persistence via _defaults, transform (including idempotency and renamed columns), transform=True, and the insert/upsert paths.

Full suite: 1513 passed, 16 skipped. black, flake8, mypy, pyright and cog --check all pass.


📚 Documentation preview 📚: https://sqlite-utils--898.org.readthedocs.build/en/898/

Adds a new unique= argument to Database.create_table(), Table.create(),
Table.transform() and the table-creating insert/upsert methods
(insert, insert_all, upsert, upsert_all). A string names a single
column and a tuple names a compound constraint spanning several
columns, so unique=["email"] and unique=[("account_id", "email")]
are both supported. The argument is also available as a table
default via db.table(..., unique=[...]).

Also adds a table.uniques introspection property that lists the
UNIQUE constraints on a table, mirroring table.checks.

Refs simonw#558
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