Skip to content

Commit 2fcb014

Browse files
Fix jobs table generation for uuid FK-derived primary keys (#1515)
Job._generate_definition() emitted attr.type (the backend-resolved SQL type, e.g. binary(16) for a uuid attribute) into a fresh DataJoint definition string. That resolved type is not valid DataJoint definition syntax, so declaring the ~~jobs table raised 'Unsupported attribute type binary(16)' on the first .jobs access (including inside populate(reserve_jobs=True)), and never recovered. Use attr.original_type (the DataJoint-level alias, e.g. uuid) with a fallback to attr.type, mirroring the fallback DataJoint already uses in heading.py. This makes jobs-table generation correct for every core-type alias in an FK-derived primary key (uuid, float32, ...), not just uuid. Adds a regression test: a Computed table whose primary key is FK-derived from a uuid attribute.
1 parent 52d252e commit 2fcb014

4 files changed

Lines changed: 44 additions & 2 deletions

File tree

src/datajoint/jobs.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,14 @@ def _get_fk_derived_pk_attrs(self) -> list[tuple[str, str]]:
206206
fk_attrs = []
207207
for name in target_pk:
208208
if name in fk_derived_attrs:
209-
# FK-derived: comes from a primary FK parent
209+
# FK-derived: comes from a primary FK parent.
210+
# Use original_type (the DataJoint-level alias, e.g. "uuid") when
211+
# present, falling back to the resolved SQL type. attr.type holds
212+
# the backend-resolved type (e.g. "binary(16)" for uuid), which is
213+
# not valid DataJoint definition syntax and fails to re-parse when
214+
# the jobs table is declared. Mirrors heading.py's own fallback.
210215
attr = heading[name]
211-
fk_attrs.append((name, attr.type))
216+
fk_attrs.append((name, attr.original_type or attr.type))
212217
else:
213218
# Native PK attribute - not from FK
214219
logger.warning(

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ def schema_uuid(connection_test, prefix):
863863
connection=connection_test,
864864
)
865865
schema(schema_uuid_module.Basic)
866+
schema(schema_uuid_module.BasicComputed)
866867
schema(schema_uuid_module.Topic)
867868
schema(schema_uuid_module.Item)
868869
yield schema

tests/integration/test_jobs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from datajoint.jobs import ERROR_MESSAGE_LENGTH, TRUNCATION_APPENDIX
88

99
from tests import schema
10+
from tests.schema_uuid import BasicComputed
1011

1112

1213
def test_reserve_job(clean_jobs, subject, experiment):
@@ -206,3 +207,26 @@ def test_jobs_refresh_with_keep_completed(clean_jobs, subject, experiment):
206207

207208
# Calling refresh again should not raise semantic matching error
208209
experiment.jobs.refresh() # This was failing before the fix
210+
211+
212+
def test_jobs_table_uuid_fk_derived_pk(schema_uuid):
213+
"""Jobs table generation must handle uuid-typed FK-derived primary keys (#1515).
214+
215+
The auto-generated jobs table definition previously leaked the resolved SQL
216+
type (binary(16)) for a uuid PK attribute instead of the DataJoint alias
217+
(uuid), so declaring the ~~table raised
218+
"Unsupported attribute type binary(16)" on first .jobs access.
219+
"""
220+
# Definition must carry the DataJoint alias, not the resolved SQL type.
221+
definition = BasicComputed.jobs.definition
222+
assert "uuid" in definition
223+
assert "binary(16)" not in definition
224+
225+
# First .jobs access declares the ~~table; this is where the bug fired.
226+
BasicComputed.jobs.refresh()
227+
assert BasicComputed.jobs.is_declared
228+
229+
# The declared PK attribute round-trips back to uuid / binary(16).
230+
pk = BasicComputed.jobs.heading.primary_key
231+
assert "item" in pk
232+
assert BasicComputed.jobs.heading["item"].original_type == "uuid"

tests/schema_uuid.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ class Basic(dj.Manual):
1414
"""
1515

1616

17+
class BasicComputed(dj.Computed):
18+
definition = """
19+
# Computed table whose primary key is FK-derived from a uuid attribute
20+
-> Basic
21+
---
22+
value : int32
23+
"""
24+
25+
def make(self, key):
26+
self.insert1(dict(key, value=1))
27+
28+
1729
class Topic(dj.Manual):
1830
definition = """
1931
# A topic for items

0 commit comments

Comments
 (0)