Skip to content

Commit e56a5a6

Browse files
fix: generate COMMENT ON COLUMN for PostgreSQL blob codecs
PostgreSQL doesn't support inline column comments in CREATE TABLE. Column comments contain type specifications (e.g., :<blob>:comment) needed for codec association. Generate separate COMMENT ON COLUMN statements in post_ddl for PostgreSQL. Changes: - compile_attribute now returns (name, sql, store, comment) - prepare_declare tracks column_comments dict - declare generates COMMENT ON COLUMN statements for PostgreSQL Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent a4ed877 commit e56a5a6

File tree

1 file changed

+20
-6
lines changed

1 file changed

+20
-6
lines changed

src/datajoint/declare.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def compile_foreign_key(
309309

310310
def prepare_declare(
311311
definition: str, context: dict, adapter
312-
) -> tuple[str, list[str], list[str], list[str], list[str], list[str], dict[str, tuple[str, str]]]:
312+
) -> tuple[str, list[str], list[str], list[str], list[str], list[str], dict[str, tuple[str, str]], dict[str, str]]:
313313
"""
314314
Parse a table definition into its components.
315315
@@ -325,7 +325,7 @@ def prepare_declare(
325325
Returns
326326
-------
327327
tuple
328-
Seven-element tuple containing:
328+
Eight-element tuple containing:
329329
330330
- table_comment : str
331331
- primary_key : list[str]
@@ -334,6 +334,7 @@ def prepare_declare(
334334
- index_sql : list[str]
335335
- external_stores : list[str]
336336
- fk_attribute_map : dict[str, tuple[str, str]]
337+
- column_comments : dict[str, str] - Column name to comment mapping
337338
"""
338339
# split definition into lines
339340
definition = re.split(r"\s*\n\s*", definition.strip())
@@ -349,6 +350,7 @@ def prepare_declare(
349350
index_sql = []
350351
external_stores = []
351352
fk_attribute_map = {} # child_attr -> (parent_table, parent_attr)
353+
column_comments = {} # column_name -> comment (for PostgreSQL COMMENT ON)
352354

353355
for line in definition:
354356
if not line or line.startswith("#"): # ignore additional comments
@@ -370,14 +372,16 @@ def prepare_declare(
370372
elif re.match(r"^(unique\s+)?index\s*.*$", line, re.I): # index
371373
compile_index(line, index_sql, adapter)
372374
else:
373-
name, sql, store = compile_attribute(line, in_key, foreign_key_sql, context, adapter)
375+
name, sql, store, comment = compile_attribute(line, in_key, foreign_key_sql, context, adapter)
374376
if store:
375377
external_stores.append(store)
376378
if in_key and name not in primary_key:
377379
primary_key.append(name)
378380
if name not in attributes:
379381
attributes.append(name)
380382
attribute_sql.append(sql)
383+
if comment:
384+
column_comments[name] = comment
381385

382386
return (
383387
table_comment,
@@ -387,6 +391,7 @@ def prepare_declare(
387391
index_sql,
388392
external_stores,
389393
fk_attribute_map,
394+
column_comments,
390395
)
391396

392397

@@ -450,6 +455,7 @@ def declare(
450455
index_sql,
451456
external_stores,
452457
fk_attribute_map,
458+
column_comments,
453459
) = prepare_declare(definition, context, adapter)
454460

455461
# Add hidden job metadata for Computed/Imported tables (not parts)
@@ -507,6 +513,13 @@ def declare(
507513
if table_comment_ddl:
508514
post_ddl.append(table_comment_ddl)
509515

516+
# Add column-level comments DDL if needed (PostgreSQL)
517+
# Column comments contain type specifications like :<blob>:user_comment
518+
for col_name, comment in column_comments.items():
519+
col_comment_ddl = adapter.column_comment_ddl(full_table_name, col_name, comment)
520+
if col_comment_ddl:
521+
post_ddl.append(col_comment_ddl)
522+
510523
return sql, external_stores, primary_key, fk_attribute_map, pre_ddl, post_ddl
511524

512525

@@ -798,7 +811,7 @@ def substitute_special_type(match: dict, category: str, foreign_key_sql: list[st
798811

799812
def compile_attribute(
800813
line: str, in_key: bool, foreign_key_sql: list[str], context: dict, adapter
801-
) -> tuple[str, str, str | None]:
814+
) -> tuple[str, str, str | None, str | None]:
802815
"""
803816
Convert an attribute definition from DataJoint format to SQL.
804817
@@ -818,11 +831,12 @@ def compile_attribute(
818831
Returns
819832
-------
820833
tuple
821-
Three-element tuple:
834+
Four-element tuple:
822835
823836
- name : str - Attribute name
824837
- sql : str - SQL column declaration
825838
- store : str or None - External store name if applicable
839+
- comment : str or None - Column comment (for PostgreSQL COMMENT ON)
826840
827841
Raises
828842
------
@@ -900,4 +914,4 @@ def compile_attribute(
900914
default=match["default"] if match["default"] else None,
901915
comment=match["comment"] if match["comment"] else None,
902916
)
903-
return match["name"], sql, match.get("store")
917+
return match["name"], sql, match.get("store"), match["comment"] if match["comment"] else None

0 commit comments

Comments
 (0)