Skip to content

Commit 58534fb

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 58534fb

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
@@ -1100,25 +1100,35 @@ 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(self.heading.attributes[attr_name].nullable for attr_name in fk_props["attr_map"])
1108+
if is_nullable:
1109+
fk_options.append("nullable")
1110+
1111+
# Check for index properties (unique, etc.)
11041112
try:
11051113
index_props = indexes.pop(tuple(fk_props["attr_map"]))
11061114
except KeyError:
1107-
index_props = ""
1115+
pass
11081116
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 ""
1117+
fk_options.extend(k for k, v in index_props.items() if v)
1118+
1119+
# Format options as " [opt1, opt2]" or empty string
1120+
options_str = " [{}]".format(", ".join(fk_options)) if fk_options else ""
11111121

11121122
if not fk_props["aliased"]:
11131123
# simple foreign key
1114-
definition += "->{props} {class_name}\n".format(
1115-
props=index_props,
1124+
definition += "->{options} {class_name}\n".format(
1125+
options=options_str,
11161126
class_name=lookup_class_name(parent_name, context) or parent_name,
11171127
)
11181128
else:
11191129
# projected foreign key
1120-
definition += "->{props} {class_name}.proj({proj_list})\n".format(
1121-
props=index_props,
1130+
definition += "->{options} {class_name}.proj({proj_list})\n".format(
1131+
options=options_str,
11221132
class_name=lookup_class_name(parent_name, context) or parent_name,
11231133
proj_list=",".join(
11241134
'{}="{}"'.format(attr, ref) for attr, ref in fk_props["attr_map"].items() if ref != attr

0 commit comments

Comments
 (0)