Your declared key is metadata
Watch a duplicate land despite a PRIMARY KEY, then see which constraints actually reject a write.
See the proof →Delta's enforced-vs-informational split: which constraints actually block writes, the RELY optimizer foot-gun, and the pipeline-code enforcement pattern.
Built for engineers who need an answer they can test in the next notebook, job run, or incident review.
Watch a duplicate land despite a PRIMARY KEY, then see which constraints actually reject a write.
See the proof →Move business-key enforcement into the pipeline, understand CHECK's sharp edges, and treat RELY as a production risk.
Apply the pattern →No. Audit the damage, repair the write path, and leave optimizer trust off until the data proves it.
Get the answer →Last verified against official Databricks documentation: September 30, 2026. Correction history: Sep 30, 2026: corrected the CHECK protocol claim (it raises the minimum writer version; affects writers, not readers).
If you migrated from Postgres or SQL Server, your muscle memory says: declare a PRIMARY KEY and duplicates get rejected. On Databricks, that reflex will cost you.
PRIMARY KEY, FOREIGN KEY, and UNIQUE constraints on Databricks are informational only — metadata the optimizer can use, never guardrails that block writes. The official docs are blunt (last verified September 29, 2026): “Primary key, foreign key, and unique constraints are informational only and aren't enforced.”
Only two constraint types actually bite: NOT NULL and CHECK. Violate one and the entire write fails atomically — Delta Lake raises InvariantViolationException and nothing is committed.
CREATE TABLE demo.orders (
order_id BIGINT NOT NULL,
amount DECIMAL(10,2),
CONSTRAINT orders_pk PRIMARY KEY (order_id)
) USING DELTA;
INSERT INTO demo.orders VALUES (1, 99.50), (1, 41.00);
-- Succeeds. No error. Both rows land.
SELECT order_id, COUNT(*) AS n
FROM demo.orders
GROUP BY order_id
HAVING COUNT(*) > 1;
order_id 1, n 2. The declared PRIMARY KEY did nothing. That is by design, not a bug.A team declares PKs and FKs across their bronze tables and discovers — usually in an audit, sometimes from a downstream customer — that duplicate business keys have been flowing in for weeks. The Databricks Community forums carry this exact story: “I created a table with Primary Key, though it doesnt act like Primary Key and is taking duplicate values on the key column.”
Dedupe the source before you write (still the cheapest duplicate fix), or guard domain invariants with a real CHECK:
ALTER TABLE demo.orders
ADD CONSTRAINT positive_amount CHECK (amount > 0);
INSERT INTO demo.orders VALUES (2, -5.00);
-- Fails: InvariantViolationException.
-- The entire write is rejected; nothing commits.
But CHECK has four sharp edges, all verified against the official docs on September 29, 2026:
ADD CONSTRAINT is a full scan, not instant DDL, so plan a window.amount IS NULL OR amount > 0 or tighten with NOT NULL.Declaring a constraint with RELY (for example PRIMARY KEY (order_id) RELY) tells the optimizer your data satisfies it, unlocking rewrites like join elimination and DISTINCT simplification on Photon. The default is NORELY, and NORELY is the safe setting. If the data violates a RELY constraint, queries silently return wrong results — and per the docs, “It is the user's responsibility to ensure the constraint is satisfied.” Never set RELY on a constraint you have not proven with the audit query below.
In Delta Live Tables, dp.expect's default action is warn — invalid records are still written to the target; only metrics are logged. If you want the bad rows gone, spell it out: dp.expect_or_drop drops them before data is written, and dp.expect_or_fail fails the whole update (manual intervention is required before reprocessing).
Verified September 29, 2026: Unity Catalog only — hive_metastore relations do not support primary key constraints. Primary key columns must be NOT NULL; at most one primary key per table. A foreign key must reference a PRIMARY KEY — or, on Databricks Runtime 18.2 and above, a UNIQUE constraint. UNIQUE is still Public Preview on 18.2+, and NULLs are treated as distinct from each other. CTAS statements don't support the constraint clause.
Nothing is corrupt. Declared primary keys on Databricks are informational only — never enforced, by design. Run the audit query below to measure the damage, fix the pipeline (dedupe the source before you write, or MERGE on the key), and keep declared constraints as documentation and lineage metadata. Leave RELY off until you have proven the constraint against the data. If you need a hard block at write time, NOT NULL and CHECK are your only real guardrails.
-- 1. Find duplicate keys your declared PK/FK never prevented
SELECT order_id, COUNT(*) AS n
FROM demo.orders
GROUP BY order_id
HAVING COUNT(*) > 1;
-- 2. List what constraints are actually declared (informational vs enforced)
SELECT constraint_name, constraint_type
FROM main.information_schema.table_constraints
WHERE table_schema = 'demo' AND table_name = 'orders';
dp.expect's default warn as a data-quality gate (invalid records are still written).Start with the official constraint semantics, then practice production data-engineering patterns.
Official reference: Constraints | Databricks on AWS
Practice path: DataCamp data engineering
Partner links: we may earn a commission if you enroll through these recommendations, at no extra cost to you.
Lakehouse Digest publishes compact, testable guidance for production Databricks work: one tactic, one implementation pattern, and one hard developer question in every issue.