You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Attributes with names starting with underscore (`_`) are **hidden**:
161
+
Attributes with names starting with an underscore (`_`) are **hidden**. The hidden-attribute mechanism is reserved for **platform-managed** columns — bookkeeping that DataJoint itself adds to support the data pipeline — and is intentionally not exposed for user-defined attributes. Attempting to declare an attribute name with a leading underscore raises:
162
162
163
-
```python
164
-
definition ="""
165
-
session_id : int32
166
-
---
167
-
result : float64
168
-
_job_start_time : datetime(3) # hidden
169
-
_job_duration : float32 # hidden
170
-
"""
163
+
```text
164
+
DataJointError: Attribute name in line "_hidden: bool" starts with an underscore.
165
+
Names with leading underscore are reserved for platform-managed columns
166
+
(e.g. _job_start_time, _singleton). Use a regular attribute name; if you
167
+
need to control visibility at the call site, use proj().
171
168
```
172
169
173
-
**Behavior:**
170
+
**Platform-managed hidden attributes** are added automatically when DataJoint declares certain table types. Users do not write these in the definition; the framework injects them programmatically after parsing.
| String restrictions | Included (passed to SQL) |
172
+
| Hidden attribute | Added to | Purpose |
173
+
|------------------|----------|---------|
174
+
|`_job_start_time`|`Computed`, `Imported`| Wall-clock start of the populate call |
175
+
|`_job_duration`|`Computed`, `Imported`| Elapsed seconds for the populate call |
176
+
|`_job_version`|`Computed`, `Imported`| Library version that produced the row |
177
+
|`_singleton`| Singleton tables | Implementation detail of the singleton pattern |
178
+
179
+
These columns are populated by DataJoint internals via raw SQL during the `populate()` lifecycle, not via `insert`/`update1`. They are filtered out of every public API surface so they don't clutter joins, fetches, or displays.
184
180
185
-
**Accessing hidden attributes:**
181
+
**Behavior.** The filter is implemented in `Heading.attributes`, which all visible code paths consume; raw SQL strings bypass it.
**Why users can't declare them.** Allowing user-defined hidden attributes would expose a feature with no public-API write path (`insert`/`update1` reject the keys; `ignore_extra_fields=True` drops them silently), no `describe()` round-trip (the regenerated definition would be missing the column), and silent filtering on dict restrictions. The cases users typically reach for hidden attributes — most commonly an index-backing derived column — are better served by a regular attribute.
**Use a regular attribute instead.** When you want a column that's part of the schema-level contract (backing an index, storing a derived value, etc.) but isn't featured in default displays, declare it as a regular attribute and use `proj()` at the call site if you want to omit it from a particular query result. For example, a hash column backing a unique index:
0 commit comments