From 7e29dad0480ab497f90365c97073b589eb25a99c Mon Sep 17 00:00:00 2001 From: Dimitri Yatsenko Date: Thu, 10 Sep 2026 13:44:29 -0500 Subject: [PATCH] docs: a new dimension in an autopopulated table requires a part table The dimensions discussion said "Computed tables never introduce dimensions" and then, in a separate section, that part tables can. Two problems: the rule was scoped to Computed when it holds for any autopopulated table (Imported too), and stating it as a prohibition buries the thing a designer actually needs, which is where the new dimension goes. Merge the two sections and state it positively: an autopopulated master inherits its whole primary key and introduces no dimension of its own, so a new dimension goes in a part table. Both code examples are kept -- the master case and the part case now read as one argument. Note that master and part rows insert in one transaction, so the new dimension is populated atomically with the computation that defines it. Generalize the grain bullet from "a computed table's grain" to "an autopopulated table's grain", and carry the same reframing into the two how-to pages that repeated the old claim: - how-to/read-diagrams.ipynb: the underlining "key rules" - how-to/model-relationships.ipynb: the 1:1-extension note --- src/explanation/entity-integrity.md | 23 ++++++++++++++--------- src/how-to/model-relationships.ipynb | 2 +- src/how-to/read-diagrams.ipynb | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/explanation/entity-integrity.md b/src/explanation/entity-integrity.md index 2bb05b83..709715f6 100644 --- a/src/explanation/entity-integrity.md +++ b/src/explanation/entity-integrity.md @@ -239,7 +239,7 @@ this table?"* - Adding a dimension makes the grain **finer**: a part table that adds `blob_idx` (`Detection.Blob` below) has grain **(… × blob)** — one row per blob of a detection. -- A computed table's grain is the combination of dimensions at which its `make()` +- An autopopulated table's grain is the combination of dimensions at which its `make()` produces rows — its [`key_source`](../reference/specs/autopopulate.md). *A computation operates at its grain.* @@ -305,11 +305,12 @@ class SubjectProfile(dj.Manual): one profile per subject. In schema diagrams, such tables have **non-underlined names**. -### Computed tables never introduce dimensions +### Autopopulated tables introduce dimensions only through part tables -A `Computed` table's primary key is fully inherited from its dependencies. -New entity types are introduced by Manual or Lookup tables, not by -computation: +An autopopulated table — `Computed` or `Imported` — runs its `make()` once per +key in its [`key_source`](../reference/specs/autopopulate.md), so the master's +primary key is fully inherited from its dependencies. The master introduces no +dimension of its own: ```python @schema @@ -322,10 +323,8 @@ class SessionSummary(dj.Computed): """ ``` -### Part tables CAN introduce dimensions - -Unlike Computed master tables, part tables can introduce new dimensions -when a single computation produces multiple related results: +When one `make()` call produces several results that need their own identifier, +that new dimension goes in a **part table**: ```python @schema @@ -350,6 +349,12 @@ class Detection(dj.Computed): `Detection` inherits its dimensions; `Detection.Blob` introduces `blob_idx` to identify individual blobs within each detection. +> **Introducing a new dimension in an autopopulated table requires a part +> table.** + +The master row and its part rows are inserted together in one transaction, so +the new dimension is populated atomically with the computation that defines it. + ### Dimensions and attribute lineage Every foreign-key attribute traces back to the dimension where it was first diff --git a/src/how-to/model-relationships.ipynb b/src/how-to/model-relationships.ipynb index cdf01bfd..74e5c195 100644 --- a/src/how-to/model-relationships.ipynb +++ b/src/how-to/model-relationships.ipynb @@ -1657,7 +1657,7 @@ "source": [ "**Thick solid line** to a **red (Computed) table** that is **not underlined**.\n", "\n", - "Computed tables never introduce dimensions — their primary key is entirely inherited from dependencies." + "An autopopulated master introduces no dimension of its own — its primary key is entirely inherited from dependencies. A new dimension in an autopopulated table requires a part table." ] }, { diff --git a/src/how-to/read-diagrams.ipynb b/src/how-to/read-diagrams.ipynb index 2d5f2a2c..e7d4811b 100644 --- a/src/how-to/read-diagrams.ipynb +++ b/src/how-to/read-diagrams.ipynb @@ -499,8 +499,8 @@ "| Not underlined | Exists in the space defined by dimensions from referenced tables |\n", "\n", "**Key rules:**\n", - "- Computed tables **never** introduce dimensions (always non-underlined)\n", - "- Part tables **can** introduce dimensions (may be underlined)" + "- An autopopulated master (`Computed`, `Imported`) is always non-underlined — its primary key is fully inherited from its dependencies\n", + "- A part table **can** be underlined; a part table is the only way an autopopulated table introduces a new dimension" ] }, {