dj.Entry, dj.Ingest and dj.Compute as tier names on one axis - #1558
Merged
Merged
Conversation
dimitri-yatsenko
requested review from
MilagrosMarin,
lum-agilyti and
ttngu207
September 30, 2026 22:13
The populated tiers sit on inconsistent axes. `Manual` names the writer but
means the origin; `Imported` names the origin but means the writer; `Computed`
names the result. A reader reasoning from the names alone lands in the wrong
tier, and the recognizable outcome is an `Imported` table with no make() and a
permanent allow_direct_insert=True papering over a modeling error.
The new names put all of them on one question -- what puts rows in this table --
and the grammar carries it: nouns are tables something else fills, verbs are
precisely the two things populate() does.
Lookup noun the code, via contents
Entry noun a writer outside the table
Ingest verb the table's own make(), reading an external source
Compute verb the table's own make(), deriving from other tables
These are assignments, not subclasses, so a table declared either way is the
same class: same SQL prefix, same Role, same tier detection, same DDL. That is
not a property to be maintained but one that cannot be broken.
This is the 2.3.4 half of #1546: the names become available and nothing else
changes. Defaults, repr, diagram labels and what the documentation teaches stay
on the old names until 2.4. `Manual`, `Imported` and `Computed` are permanent
aliases -- no deprecation, no migration, no broken tutorials or third-party
code, ever.
dimitri-yatsenko
force-pushed
the
feat/tier-aliases
branch
from
October 1, 2026 15:30
c8be99f to
ab4a4ce
Compare
lum-agilyti
approved these changes
Oct 1, 2026
lum-agilyti
left a comment
There was a problem hiding this comment.
Approving. The aliases are the same objects as the old classes, so prefix, Role and tier detection can't diverge. A few notes on the tests:
- test_lookup_and_part_are_unchanged: assert not hasattr(dj, "LookupAlias") always passes, since nothing is or would be named that.
- test_declaring_either_way_produces_the_same_table_name doesn't compare the two tables. from_camel_case("Subject") doesn't involve ViaOld/ViaNew, and the _prefix and type(...) checks already follow from test_alias_is_the_same_class. Nothing checks that both spellings produce the same CREATE TABLE.
- The module docstring lists lookup_class_name among the checks, but no test calls it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The 2.3.4 half of #1546: the new names become available, and nothing else changes.
Why
The populated tiers sit on inconsistent axes.
Manualnames the writer but means the origin;Importednames the origin but means the writer;Computednames the result. A reader reasoning from the names alone lands in the wrong tier, and the failure has a recognizable shape: anImportedtable with nomake(),populate()silently doing nothing, and a permanentallow_direct_insert=Truesuppressing a guard that was reporting a real modeling error.The new names put all four on one question — what puts rows in this table? — and the grammar carries it: the nouns are tables something else fills, the verbs are precisely the two things
populate()does.LookupcontentsEntryIngestmake(), reading an external sourceComputemake(), deriving from other DataJoint tablesAliases, not subclasses
Three assignments. A table declared either way is the same class — same SQL prefix, same
Role, same tier detection, sameCREATE TABLE. That is not an invariant someone has to maintain; it is one that cannot be broken, which is why this is three lines rather than a parallel hierarchy.LookupandPartare unchanged:Lookupalready sits on the axis, andPartis a structural role rather than a fourth answer to the same question.What does not change in 2.3.4
Defaults,
repr, introspection,dj.Diagramtier labels, and what the documentation teaches all stay on the old names. Early adopters and new examples can use the new ones immediately with zero migration; the terminology sweep is 2.4.Manual,ImportedandComputedare permanent aliases — no deprecation at any point, no migration, no broken tutorials, no broken third-party code. The names have been in constant use for a decade and they keep working indefinitely.Verification
dj.Entry,dj.Ingest,dj.Compute(keepManual/Imported/Computedas permanent aliases) #1546 asks for: identity rather than subclassing, SQL prefix againstRole, package exports, tier detection by prefix for all five tiers, and thatLookup/Partare untouched.class ViaOld(dj.Manual)andclass ViaNew(dj.Entry)with the same definition emit byte-identicalCREATE TABLE.ruff,ruff-format,codespell,mypypass via pre-commit.Note on naming, from the #1546 discussion
Computerather thanDerive: in relational databases a derived table is the result of a query — computed on read, not stored — which is the opposite of this tier, whose rows are materialized bymake()and persisted with lineage.Derivewould collide head-on with that meaning for exactly our most database-literate readers.The verb-as-class-name cost raised by @gtouloumes is real and accepted:
class TuningCurve(dj.Compute)takes getting used to. It is an adoption cost, not a correctness objection, and the docs reinforce the axis where the names are introduced.