<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Declaring a Primary Key RELY turned my dbt unique Test Green on Duplicate Data in Community Articles</title>
    <link>https://community.databricks.com/t5/community-articles/declaring-a-primary-key-rely-turned-my-dbt-unique-test-green-on/m-p/169864#M1611</link>
    <description>&lt;P&gt;An open dbt-databricks feature request, &lt;A href="https://github.com/databricks/dbt-databricks/issues/1271" target="_blank" rel="noopener"&gt;#1271&lt;/A&gt;, asks for native &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; support on primary keys and suggests that &lt;FONT face="courier new, courier, monospace"&gt;rely: true&lt;/FONT&gt; "implicitly create the &lt;FONT face="courier new, courier, monospace"&gt;not_null&lt;/FONT&gt; and &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; constraints" as "a safeguard against incorrect query results". Databricks does not enforce &lt;FONT face="courier new, courier, monospace"&gt;UNIQUE&lt;/FONT&gt; constraints, so only a uniqueness test would check the data. I tested whether dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test still works once the key says &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;It did not. I built two dbt models from the same source, which contains one duplicate order. Their contracts differ only in the primary key option. dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test failed on the &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; model and passed on the &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; model.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="dbt build output: the unique test fails on the NORELY model and passes on the RELY model" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31512iD239D18BC4C3FB57/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig1-dbt-build.png" alt="fig1-dbt-build.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 1.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;The same unique test on two models built from the same rows.&lt;/EM&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;WHAT THE DOCS SAY&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;"If &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, Databricks may exploit the constraint to rewrite and optimize queries. It is the user's responsibility to ensure the constraint is satisfied. Relying on a constraint that is not satisfied may lead to incorrect query results."&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-ddl-create-table-constraint" target="_blank" rel="noopener"&gt;CONSTRAINT clause, Databricks SQL reference&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;The setup&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;The source holds six orders, and order &lt;FONT face="courier new, courier, monospace"&gt;3&lt;/FONT&gt; appears twice with different amounts, as a replayed event would. Until #1271 lands, &lt;FONT face="courier new, courier, monospace"&gt;expression&lt;/FONT&gt; does the job: dbt-databricks appends it to the primary key DDL, so this contract creates &lt;FONT face="courier new, courier, monospace"&gt;PRIMARY KEY (order_id) RELY&lt;/FONT&gt;.&lt;/P&gt;&lt;PRE&gt;models:
  - name: orders_rely
    config:
      contract: {enforced: true}
    constraints:
      - type: primary_key
        columns: [order_id]
        expression: RELY          # the control model uses NORELY, the default
    columns:
      - name: order_id
        data_type: bigint
        constraints: [{type: not_null}]
        data_tests: [unique]
      # customer and amount columns omitted&lt;/PRE&gt;&lt;P&gt;Both models keep the duplicate: filtering on &lt;FONT face="courier new, courier, monospace"&gt;order_id = 3&lt;/FONT&gt; returns two rows from each. I ran everything on a serverless SQL warehouse (Photon, DBSQL 2026.36) with dbt-core 1.12.3 and dbt-databricks 1.12.5. The docs say these rewrites need Photon; I did not test other compute.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Why the test passes&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test groups by the column and returns the groups where &lt;FONT face="courier new, courier, monospace"&gt;count(*) &amp;gt; 1&lt;/FONT&gt;. If &lt;FONT face="courier new, courier, monospace"&gt;order_id&lt;/FONT&gt; is unique, each group holds one row and &lt;FONT face="courier new, courier, monospace"&gt;count(*) &amp;gt; 1&lt;/FONT&gt; cannot be true. With &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, the optimizer takes the key at its word and replaces the query with an empty result. The physical plans, trimmed:&lt;/P&gt;&lt;PRE&gt;-- PRIMARY KEY NORELY
PhotonFilter (n_records &amp;gt; 1)
+- PhotonGroupingAgg(keys=[order_id], functions=[count(1)])
   +- PhotonScan parquet workspace.rely_lab_dbt.orders_norely[order_id]

-- PRIMARY KEY RELY
LocalTableScan &amp;lt;empty&amp;gt;, [unique_field, n_records]&lt;/PRE&gt;&lt;P&gt;A larger table behaved the same way. On 1,000,010 rows in 16 files with 10 duplicated keys, the &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; run found all 10 and read every row. The &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; run found none and read no rows, and &lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT order_id)&lt;/FONT&gt; on the same table returned 1,000,010 instead of 1,000,000.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="system.query.history result: the NORELY run read 1,000,010 rows from 16 files and found 10 duplicate keys; the RELY run read 0 rows from 0 files and found 0" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31510i7E3905E763FF6AE1/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig2-query-history.png" alt="fig2-query-history.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 2.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;The same duplicate-key query in &lt;FONT face="courier new, courier, monospace"&gt;system.query.history&lt;/FONT&gt;. The RELY run opened no files.&lt;/EM&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Which checks go blind&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;I loaded the same six rows into tables with no key, a &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; key and a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; key. The first two matched in every check.&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;Check&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;No key or NORELY&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;RELY&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;dbt &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; (&lt;FONT face="courier new, courier, monospace"&gt;GROUP BY … HAVING COUNT(*) &amp;gt; 1&lt;/FONT&gt;)&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;1 duplicate key&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;0&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;PySpark &lt;FONT face="courier new, courier, monospace"&gt;groupBy("order_id").count().filter("count &amp;gt; 1")&lt;/FONT&gt;, serverless job&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;0&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT order_id)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;5&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;6&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;LEFT JOIN&lt;/FONT&gt; to a customer table with a duplicate key, row count&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;8&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;6&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;COUNT(*) OVER (PARTITION BY order_id) &amp;gt; 1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;2 rows&lt;/TD&gt;&lt;TD&gt;2 rows&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;DQX 0.16.0 &lt;FONT face="courier new, courier, monospace"&gt;is_unique&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;2 rows flagged&lt;/TD&gt;&lt;TD&gt;2 rows flagged&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;The fan-out check missed because the optimizer dropped the join: with a unique customer key, a &lt;FONT face="courier new, courier, monospace"&gt;LEFT JOIN&lt;/FONT&gt; cannot add rows.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="SQL editor result comparing total rows, distinct keys, duplicate keys found and LEFT JOIN rows for the no-key, NORELY and RELY tables" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31511i9F62EE86BCA1A025/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig3-summary-grid.png" alt="fig3-summary-grid.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 3.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;One query over three tables with identical rows. The RELY row reports six distinct keys, no duplicates and no join fan-out.&lt;/EM&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;What to do about it&lt;/FONT&gt;&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Find your RELY keys.&lt;/STRONG&gt; &lt;FONT face="courier new, courier, monospace"&gt;information_schema.table_constraints&lt;/FONT&gt; returns the same row for a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; and a &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; key. &lt;FONT face="courier new, courier, monospace"&gt;SHOW CREATE TABLE&lt;/FONT&gt; and &lt;FONT face="courier new, courier, monospace"&gt;DESCRIBE TABLE EXTENDED&lt;/FONT&gt; show the option.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Validate before you declare RELY.&lt;/STRONG&gt; Check uniqueness on the staging table or incoming batch, before rows reach a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; table, and declare &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; only where the writer guarantees uniqueness. Ingestion that can replay events does not.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Count with a window in dbt.&lt;/STRONG&gt; A &lt;FONT face="courier new, courier, monospace"&gt;databricks__test_unique&lt;/FONT&gt; macro in your project replaces the built-in test on Databricks. With this version, the &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; model's test failed with 2 rows, one per duplicated row. Measure its runtime on your largest models before you switch.&lt;/LI&gt;&lt;/UL&gt;&lt;PRE&gt;{% macro databricks__test_unique(model, column_name) %}
select unique_field, n_records
from (
    select {{ column_name }} as unique_field,
           count(*) over (partition by {{ column_name }}) as n_records
    from {{ model }}
    where {{ column_name }} is not null
) counted
where n_records &amp;gt; 1
{% endmacro %}&lt;/PRE&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;DQX caught it.&lt;/STRONG&gt; &lt;FONT face="courier new, courier, monospace"&gt;is_unique&lt;/FONT&gt; in DQX 0.16.0 counts with a window function and flagged both rows here and all 20 in the million-row table.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Check the check.&lt;/STRONG&gt; If &lt;FONT face="courier new, courier, monospace"&gt;EXPLAIN&lt;/FONT&gt; shows no scan of the table, or query history shows 0 rows read, the check tested nothing.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;The window-based checks held in these runs. I found no documentation promising they will keep working, so re-test after upgrades.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Conclusion&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;A &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; key changes the answers of the queries meant to verify it. Here, dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test, a PySpark &lt;FONT face="courier new, courier, monospace"&gt;groupBy&lt;/FONT&gt;, &lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT)&lt;/FONT&gt; and a join fan-out check all missed a duplicate key that window-based checks caught. Whatever safeguard #1271 adds should validate uniqueness before the key says &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, or count with a window.&lt;/P&gt;</description>
    <pubDate>Fri, 25 Sep 2026 18:30:18 GMT</pubDate>
    <dc:creator>ivanvyd</dc:creator>
    <dc:date>2026-09-25T18:30:18Z</dc:date>
    <item>
      <title>Declaring a Primary Key RELY turned my dbt unique Test Green on Duplicate Data</title>
      <link>https://community.databricks.com/t5/community-articles/declaring-a-primary-key-rely-turned-my-dbt-unique-test-green-on/m-p/169864#M1611</link>
      <description>&lt;P&gt;An open dbt-databricks feature request, &lt;A href="https://github.com/databricks/dbt-databricks/issues/1271" target="_blank" rel="noopener"&gt;#1271&lt;/A&gt;, asks for native &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; support on primary keys and suggests that &lt;FONT face="courier new, courier, monospace"&gt;rely: true&lt;/FONT&gt; "implicitly create the &lt;FONT face="courier new, courier, monospace"&gt;not_null&lt;/FONT&gt; and &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; constraints" as "a safeguard against incorrect query results". Databricks does not enforce &lt;FONT face="courier new, courier, monospace"&gt;UNIQUE&lt;/FONT&gt; constraints, so only a uniqueness test would check the data. I tested whether dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test still works once the key says &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;It did not. I built two dbt models from the same source, which contains one duplicate order. Their contracts differ only in the primary key option. dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test failed on the &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; model and passed on the &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; model.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="dbt build output: the unique test fails on the NORELY model and passes on the RELY model" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31512iD239D18BC4C3FB57/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig1-dbt-build.png" alt="fig1-dbt-build.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 1.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;The same unique test on two models built from the same rows.&lt;/EM&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;WHAT THE DOCS SAY&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;"If &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, Databricks may exploit the constraint to rewrite and optimize queries. It is the user's responsibility to ensure the constraint is satisfied. Relying on a constraint that is not satisfied may lead to incorrect query results."&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-ddl-create-table-constraint" target="_blank" rel="noopener"&gt;CONSTRAINT clause, Databricks SQL reference&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;The setup&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;The source holds six orders, and order &lt;FONT face="courier new, courier, monospace"&gt;3&lt;/FONT&gt; appears twice with different amounts, as a replayed event would. Until #1271 lands, &lt;FONT face="courier new, courier, monospace"&gt;expression&lt;/FONT&gt; does the job: dbt-databricks appends it to the primary key DDL, so this contract creates &lt;FONT face="courier new, courier, monospace"&gt;PRIMARY KEY (order_id) RELY&lt;/FONT&gt;.&lt;/P&gt;&lt;PRE&gt;models:
  - name: orders_rely
    config:
      contract: {enforced: true}
    constraints:
      - type: primary_key
        columns: [order_id]
        expression: RELY          # the control model uses NORELY, the default
    columns:
      - name: order_id
        data_type: bigint
        constraints: [{type: not_null}]
        data_tests: [unique]
      # customer and amount columns omitted&lt;/PRE&gt;&lt;P&gt;Both models keep the duplicate: filtering on &lt;FONT face="courier new, courier, monospace"&gt;order_id = 3&lt;/FONT&gt; returns two rows from each. I ran everything on a serverless SQL warehouse (Photon, DBSQL 2026.36) with dbt-core 1.12.3 and dbt-databricks 1.12.5. The docs say these rewrites need Photon; I did not test other compute.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Why the test passes&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test groups by the column and returns the groups where &lt;FONT face="courier new, courier, monospace"&gt;count(*) &amp;gt; 1&lt;/FONT&gt;. If &lt;FONT face="courier new, courier, monospace"&gt;order_id&lt;/FONT&gt; is unique, each group holds one row and &lt;FONT face="courier new, courier, monospace"&gt;count(*) &amp;gt; 1&lt;/FONT&gt; cannot be true. With &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, the optimizer takes the key at its word and replaces the query with an empty result. The physical plans, trimmed:&lt;/P&gt;&lt;PRE&gt;-- PRIMARY KEY NORELY
PhotonFilter (n_records &amp;gt; 1)
+- PhotonGroupingAgg(keys=[order_id], functions=[count(1)])
   +- PhotonScan parquet workspace.rely_lab_dbt.orders_norely[order_id]

-- PRIMARY KEY RELY
LocalTableScan &amp;lt;empty&amp;gt;, [unique_field, n_records]&lt;/PRE&gt;&lt;P&gt;A larger table behaved the same way. On 1,000,010 rows in 16 files with 10 duplicated keys, the &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; run found all 10 and read every row. The &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; run found none and read no rows, and &lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT order_id)&lt;/FONT&gt; on the same table returned 1,000,010 instead of 1,000,000.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="system.query.history result: the NORELY run read 1,000,010 rows from 16 files and found 10 duplicate keys; the RELY run read 0 rows from 0 files and found 0" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31510i7E3905E763FF6AE1/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig2-query-history.png" alt="fig2-query-history.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 2.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;The same duplicate-key query in &lt;FONT face="courier new, courier, monospace"&gt;system.query.history&lt;/FONT&gt;. The RELY run opened no files.&lt;/EM&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Which checks go blind&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;I loaded the same six rows into tables with no key, a &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; key and a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; key. The first two matched in every check.&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;Check&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;No key or NORELY&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;&lt;STRONG&gt;RELY&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;dbt &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; (&lt;FONT face="courier new, courier, monospace"&gt;GROUP BY … HAVING COUNT(*) &amp;gt; 1&lt;/FONT&gt;)&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;1 duplicate key&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;0&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;PySpark &lt;FONT face="courier new, courier, monospace"&gt;groupBy("order_id").count().filter("count &amp;gt; 1")&lt;/FONT&gt;, serverless job&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;0&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT order_id)&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;5&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;6&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;LEFT JOIN&lt;/FONT&gt; to a customer table with a duplicate key, row count&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;8&lt;/TD&gt;&lt;TD&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;6&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;&lt;FONT face="courier new, courier, monospace"&gt;COUNT(*) OVER (PARTITION BY order_id) &amp;gt; 1&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;2 rows&lt;/TD&gt;&lt;TD&gt;2 rows&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;&lt;STRONG&gt;DQX 0.16.0 &lt;FONT face="courier new, courier, monospace"&gt;is_unique&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/TD&gt;&lt;TD&gt;2 rows flagged&lt;/TD&gt;&lt;TD&gt;2 rows flagged&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;The fan-out check missed because the optimizer dropped the join: with a unique customer key, a &lt;FONT face="courier new, courier, monospace"&gt;LEFT JOIN&lt;/FONT&gt; cannot add rows.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="SQL editor result comparing total rows, distinct keys, duplicate keys found and LEFT JOIN rows for the no-key, NORELY and RELY tables" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31511i9F62EE86BCA1A025/image-size/large?v=v2&amp;amp;px=999" role="button" title="fig3-summary-grid.png" alt="fig3-summary-grid.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;FONT color="#E0661A"&gt;&lt;STRONG&gt;Figure 3.&lt;/STRONG&gt;&lt;/FONT&gt; &lt;EM&gt;One query over three tables with identical rows. The RELY row reports six distinct keys, no duplicates and no join fan-out.&lt;/EM&gt;&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;What to do about it&lt;/FONT&gt;&lt;/H2&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Find your RELY keys.&lt;/STRONG&gt; &lt;FONT face="courier new, courier, monospace"&gt;information_schema.table_constraints&lt;/FONT&gt; returns the same row for a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; and a &lt;FONT face="courier new, courier, monospace"&gt;NORELY&lt;/FONT&gt; key. &lt;FONT face="courier new, courier, monospace"&gt;SHOW CREATE TABLE&lt;/FONT&gt; and &lt;FONT face="courier new, courier, monospace"&gt;DESCRIBE TABLE EXTENDED&lt;/FONT&gt; show the option.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Validate before you declare RELY.&lt;/STRONG&gt; Check uniqueness on the staging table or incoming batch, before rows reach a &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; table, and declare &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; only where the writer guarantees uniqueness. Ingestion that can replay events does not.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Count with a window in dbt.&lt;/STRONG&gt; A &lt;FONT face="courier new, courier, monospace"&gt;databricks__test_unique&lt;/FONT&gt; macro in your project replaces the built-in test on Databricks. With this version, the &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; model's test failed with 2 rows, one per duplicated row. Measure its runtime on your largest models before you switch.&lt;/LI&gt;&lt;/UL&gt;&lt;PRE&gt;{% macro databricks__test_unique(model, column_name) %}
select unique_field, n_records
from (
    select {{ column_name }} as unique_field,
           count(*) over (partition by {{ column_name }}) as n_records
    from {{ model }}
    where {{ column_name }} is not null
) counted
where n_records &amp;gt; 1
{% endmacro %}&lt;/PRE&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;DQX caught it.&lt;/STRONG&gt; &lt;FONT face="courier new, courier, monospace"&gt;is_unique&lt;/FONT&gt; in DQX 0.16.0 counts with a window function and flagged both rows here and all 20 in the million-row table.&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Check the check.&lt;/STRONG&gt; If &lt;FONT face="courier new, courier, monospace"&gt;EXPLAIN&lt;/FONT&gt; shows no scan of the table, or query history shows 0 rows read, the check tested nothing.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;The window-based checks held in these runs. I found no documentation promising they will keep working, so re-test after upgrades.&lt;/P&gt;&lt;P align="center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="orange-rule.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/31509iC4066A97F786B51C/image-size/large?v=v2&amp;amp;px=999" role="button" title="orange-rule.png" alt="orange-rule.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;H2&gt;&lt;FONT color="#E0661A"&gt;Conclusion&lt;/FONT&gt;&lt;/H2&gt;&lt;P&gt;A &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt; key changes the answers of the queries meant to verify it. Here, dbt's &lt;FONT face="courier new, courier, monospace"&gt;unique&lt;/FONT&gt; test, a PySpark &lt;FONT face="courier new, courier, monospace"&gt;groupBy&lt;/FONT&gt;, &lt;FONT face="courier new, courier, monospace"&gt;COUNT(DISTINCT)&lt;/FONT&gt; and a join fan-out check all missed a duplicate key that window-based checks caught. Whatever safeguard #1271 adds should validate uniqueness before the key says &lt;FONT face="courier new, courier, monospace"&gt;RELY&lt;/FONT&gt;, or count with a window.&lt;/P&gt;</description>
      <pubDate>Fri, 25 Sep 2026 18:30:18 GMT</pubDate>
      <guid>https://community.databricks.com/t5/community-articles/declaring-a-primary-key-rely-turned-my-dbt-unique-test-green-on/m-p/169864#M1611</guid>
      <dc:creator>ivanvyd</dc:creator>
      <dc:date>2026-09-25T18:30:18Z</dc:date>
    </item>
  </channel>
</rss>

