Skip to content

Commit 20224ae

Browse files
docs: correct fetch/proj behavior for hidden columns; tighten error messages
Per Milagros's review on PR #162: the matrix rows for fetch("_name") and proj("_name") said "Included" but the actual behavior is "Rejected" — both route through proj()'s heading.names check (visible-only list at heading.py:236-237), which raises DataJointError. The integration test tests/integration/test_hidden_job_metadata.py:170-172 confirms this constraint by dropping to raw SQL via conn.query() to inspect hidden columns. The "Inspecting platform-managed hidden columns" example block had the same bug — the proj()/fetch1() examples would raise as written. Replaced with the raw-SQL pattern that mirrors the integration test. Also tightened the insert/update1 row: the previous parenthetical "(Field not in table heading)" was an inexact paraphrase. insert/insert1 raise KeyError("`_name` is not in the table heading") (table.py:1424); update1 raises DataJointError("Attribute `_name` not found.") (table.py:514). Split into two rows with the verbatim messages.
1 parent 832c95f commit 20224ae

1 file changed

Lines changed: 11 additions & 8 deletions

File tree

src/reference/specs/table-declaration.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,13 @@ These columns are populated by DataJoint internals via raw SQL during the `popul
186186
| `heading._attributes` (internal) | Included |
187187
| Table display / `repr` / `_repr_html_` | Excluded |
188188
| `fetch()`, `fetch1()`, `to_dicts()`, `to_pandas()` (default) | Excluded |
189-
| `fetch("_name")` / `fetch1("_name")` (explicit) | Included |
190-
| `proj("_name")` (explicit) | Included |
189+
| `fetch("_name")` / `fetch1("_name")` (explicit) | Rejected (`Attribute not found`) — use raw SQL via `conn.query(...)` |
190+
| `proj("_name")` (explicit) | Rejected (same reason) |
191191
| Natural-join namesake matching | Excluded |
192192
| Dict restriction `Table & {"_name": value}` | Silently ignored |
193193
| String restriction `Table & "_name = ..."` | Included (passes to SQL) |
194-
| `insert()`, `insert1()`, `update1()` | Rejected (`Field not in table heading`) |
194+
| `insert()`, `insert1()` | Rejected — ``KeyError("`_name` is not in the table heading")`` |
195+
| `update1()` | Rejected — ``DataJointError("Attribute `_name` not found.")`` |
195196
| `insert(..., ignore_extra_fields=True)` | Silently dropped (key not written) |
196197
| `describe()` / reverse-engineered definition | Excluded |
197198
| `unique index (..., _name)` | Allowed |
@@ -204,11 +205,13 @@ These columns are populated by DataJoint internals via raw SQL during the `popul
204205
# Default fetch — hidden columns excluded
205206
results = MyTable.to_dicts()
206207

207-
# Explicit projection promotes a hidden column to visible
208-
results = MyTable.proj('result', '_job_start_time').to_dicts()
209-
210-
# Explicit fetch by name returns hidden columns
211-
row = (MyTable & key).fetch1('result', '_job_start_time')
208+
# To inspect platform-managed hidden columns, query raw SQL.
209+
# The public API (fetch / proj) intentionally rejects them.
210+
conn = MyTable.connection
211+
rows = conn.query(
212+
f"SELECT _job_start_time, _job_duration, _job_version "
213+
f"FROM {MyTable.full_table_name}"
214+
).fetchall()
212215

213216
# String restriction works (passes through to SQL)
214217
MyTable & "_job_start_time > '2024-01-01'"

0 commit comments

Comments
 (0)