Skip to content

Commit 9a68dc7

Browse files
fix: Preserve nullable and unique modifiers in describe() for FK attributes
The describe() method now correctly outputs FK options like [nullable], [unique], or [nullable, unique] by: 1. Checking if any FK attribute has nullable=True in the heading 2. Combining nullable with existing index properties (unique, etc.) 3. Formatting all options into a single bracket notation This fixes the round-trip issue where describe() output could not be used to recreate an equivalent table definition. Fixes: describe() tests that verify definition round-trips Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f4b0258 commit 9a68dc7

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/datajoint/table.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,25 +1100,38 @@ def describe(self, context=None, printout=False):
11001100
if attr.name in fk_props["attr_map"]:
11011101
do_include = False
11021102
if attributes_thus_far.issuperset(fk_props["attr_map"]):
1103-
# foreign key properties
1103+
# foreign key properties - collect all options
1104+
fk_options = []
1105+
1106+
# Check if FK is nullable (any FK attribute has nullable=True)
1107+
is_nullable = any(
1108+
self.heading.attributes[attr_name].nullable
1109+
for attr_name in fk_props["attr_map"]
1110+
)
1111+
if is_nullable:
1112+
fk_options.append("nullable")
1113+
1114+
# Check for index properties (unique, etc.)
11041115
try:
11051116
index_props = indexes.pop(tuple(fk_props["attr_map"]))
11061117
except KeyError:
1107-
index_props = ""
1118+
pass
11081119
else:
1109-
index_props = [k for k, v in index_props.items() if v]
1110-
index_props = " [{}]".format(", ".join(index_props)) if index_props else ""
1120+
fk_options.extend(k for k, v in index_props.items() if v)
1121+
1122+
# Format options as " [opt1, opt2]" or empty string
1123+
options_str = " [{}]".format(", ".join(fk_options)) if fk_options else ""
11111124

11121125
if not fk_props["aliased"]:
11131126
# simple foreign key
1114-
definition += "->{props} {class_name}\n".format(
1115-
props=index_props,
1127+
definition += "->{options} {class_name}\n".format(
1128+
options=options_str,
11161129
class_name=lookup_class_name(parent_name, context) or parent_name,
11171130
)
11181131
else:
11191132
# projected foreign key
1120-
definition += "->{props} {class_name}.proj({proj_list})\n".format(
1121-
props=index_props,
1133+
definition += "->{options} {class_name}.proj({proj_list})\n".format(
1134+
options=options_str,
11221135
class_name=lookup_class_name(parent_name, context) or parent_name,
11231136
proj_list=",".join(
11241137
'{}="{}"'.format(attr, ref) for attr, ref in fk_props["attr_map"].items() if ref != attr

0 commit comments

Comments
 (0)