Skip to content

Commit ad127be

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 ba702d3 commit ad127be

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

src/datajoint/table.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,25 +1127,35 @@ def describe(self, context=None, printout=False):
11271127
if attr.name in fk_props["attr_map"]:
11281128
do_include = False
11291129
if attributes_thus_far.issuperset(fk_props["attr_map"]):
1130-
# foreign key properties
1130+
# foreign key properties - collect all options
1131+
fk_options = []
1132+
1133+
# Check if FK is nullable (any FK attribute has nullable=True)
1134+
is_nullable = any(self.heading.attributes[attr_name].nullable for attr_name in fk_props["attr_map"])
1135+
if is_nullable:
1136+
fk_options.append("nullable")
1137+
1138+
# Check for index properties (unique, etc.)
11311139
try:
11321140
index_props = indexes.pop(tuple(fk_props["attr_map"]))
11331141
except KeyError:
1134-
index_props = ""
1142+
pass
11351143
else:
1136-
index_props = [k for k, v in index_props.items() if v]
1137-
index_props = " [{}]".format(", ".join(index_props)) if index_props else ""
1144+
fk_options.extend(k for k, v in index_props.items() if v)
1145+
1146+
# Format options as " [opt1, opt2]" or empty string
1147+
options_str = " [{}]".format(", ".join(fk_options)) if fk_options else ""
11381148

11391149
if not fk_props["aliased"]:
11401150
# simple foreign key
1141-
definition += "->{props} {class_name}\n".format(
1142-
props=index_props,
1151+
definition += "->{options} {class_name}\n".format(
1152+
options=options_str,
11431153
class_name=lookup_class_name(parent_name, context) or parent_name,
11441154
)
11451155
else:
11461156
# projected foreign key
1147-
definition += "->{props} {class_name}.proj({proj_list})\n".format(
1148-
props=index_props,
1157+
definition += "->{options} {class_name}.proj({proj_list})\n".format(
1158+
options=options_str,
11491159
class_name=lookup_class_name(parent_name, context) or parent_name,
11501160
proj_list=",".join(
11511161
'{}="{}"'.format(attr, ref) for attr, ref in fk_props["attr_map"].items() if ref != attr

0 commit comments

Comments
 (0)