Skip to content

Commit dacf5ce

Browse files
Merge pull request #1435 from datajoint/fix/1434-migrate-not-null
fix: preserve NOT NULL constraint in migrate_columns()
2 parents fcbf7d8 + b1fe114 commit dacf5ce

1 file changed

Lines changed: 10 additions & 6 deletions

File tree

src/datajoint/migrate.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,14 @@ def analyze_columns(schema: Schema) -> dict:
142142
for (table_name,) in tables:
143143
# Get all columns for this table
144144
columns_query = """
145-
SELECT COLUMN_NAME, COLUMN_TYPE, DATA_TYPE, COLUMN_COMMENT
145+
SELECT COLUMN_NAME, COLUMN_TYPE, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE
146146
FROM information_schema.COLUMNS
147147
WHERE TABLE_SCHEMA = %s
148148
AND TABLE_NAME = %s
149149
"""
150150
columns = connection.query(columns_query, args=(schema.database, table_name)).fetchall()
151151

152-
for column_name, column_type, data_type, comment in columns:
152+
for column_name, column_type, data_type, comment, is_nullable in columns:
153153
comment = comment or ""
154154

155155
# Check if column already has a type label (starts with :type:)
@@ -167,6 +167,7 @@ def analyze_columns(schema: Schema) -> dict:
167167
"column": column_name,
168168
"native_type": column_type,
169169
"comment": comment,
170+
"is_nullable": is_nullable == "YES",
170171
}
171172

172173
if is_external:
@@ -270,9 +271,10 @@ def migrate_columns(
270271
new_comment_escaped = new_comment.replace("\\", "\\\\").replace("'", "\\'")
271272

272273
# Generate ALTER TABLE statement
274+
not_null = "" if col["is_nullable"] else " NOT NULL"
273275
sql = (
274276
f"ALTER TABLE `{db_name}`.`{table_name}` "
275-
f"MODIFY COLUMN `{col['column']}` {col['native_type']} "
277+
f"MODIFY COLUMN `{col['column']}` {col['native_type']}{not_null} "
276278
f"COMMENT '{new_comment_escaped}'"
277279
)
278280
result["sql_statements"].append(sql)
@@ -365,7 +367,7 @@ def analyze_blob_columns(schema: Schema) -> list[dict]:
365367
for (table_name,) in tables:
366368
# Get column information for each table
367369
columns_query = """
368-
SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_COMMENT
370+
SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_COMMENT, IS_NULLABLE
369371
FROM information_schema.COLUMNS
370372
WHERE TABLE_SCHEMA = %s
371373
AND TABLE_NAME = %s
@@ -374,7 +376,7 @@ def analyze_blob_columns(schema: Schema) -> list[dict]:
374376

375377
columns = connection.query(columns_query, args=(schema.database, table_name)).fetchall()
376378

377-
for column_name, column_type, comment in columns:
379+
for column_name, column_type, comment, is_nullable in columns:
378380
# Check if comment already has a codec type (starts with :type:)
379381
has_codec = comment and comment.startswith(":")
380382

@@ -385,6 +387,7 @@ def analyze_blob_columns(schema: Schema) -> list[dict]:
385387
"column_type": column_type,
386388
"current_comment": comment or "",
387389
"needs_migration": not has_codec,
390+
"is_nullable": is_nullable == "YES",
388391
}
389392
)
390393

@@ -447,9 +450,10 @@ def generate_migration_sql(
447450
db_name, table_name = col["table_name"].split(".")
448451

449452
# Generate ALTER TABLE statement
453+
not_null = "" if col.get("is_nullable", True) else " NOT NULL"
450454
sql = (
451455
f"ALTER TABLE `{db_name}`.`{table_name}` "
452-
f"MODIFY COLUMN `{col['column_name']}` {col['column_type']} "
456+
f"MODIFY COLUMN `{col['column_name']}` {col['column_type']}{not_null} "
453457
f"COMMENT '{new_comment_escaped}'"
454458
)
455459
sql_statements.append(sql)

0 commit comments

Comments
 (0)