alter() on PostgreSQL cannot change an attribute: MODIFY is a syntax error, and a comment change is ignored · Issue #1625 · datajoint/datajoint-python · GitHub
On PostgreSQL, Table.alter() can add, drop and rename attributes, but it cannot change one:
Changing an attribute's type, nullability or default raises a syntax error. _make_attribute_alter (declare.py) always emits MySQL's MODIFY <column definition>. PostgreSQL needs ALTER COLUMN ... TYPE ..., SET/DROP NOT NULL and SET/DROP DEFAULT.
Changing only an attribute's comment does nothing, silently. On PostgreSQL the comment is not part of the column definition: it is applied with COMMENT ON COLUMN. So a comment-only change compares as unchanged, and alter() reports nothing to alter.
MySQL handles all five changes.
Reproduction
DataJoint master, PostgreSQL 15 and MySQL 8.0:
importdatajointasdjschema=dj.Schema("scratch_alter_pg")
@schemaclassMeasurement(dj.Manual):
definition=""" measurement_id : int32 --- value : float32 # the value """Measurement.definition="""measurement_id : int32---value : float64 # the value"""Measurement.alter(prompt=False)
New definition of value
MySQL
PostgreSQL
value : float64 # the value
altered
QuerySyntaxError: syntax error at or near "MODIFY" (MODIFY "value" double precision NOT NULL)
value = null : float32 # the value
altered
same error (MODIFY "value" real DEFAULT NULL)
value = 1.5 : float32 # the value
altered
same error (MODIFY "value" real NOT NULL DEFAULT '1.5')
reading : float32 # the value {value} (rename)
altered
altered
value : float32 # another comment
altered
no change, no message
Expected behavior
On PostgreSQL, alter() makes the same changes it makes on MySQL:
a type change becomes ALTER COLUMN ... TYPE ..., with USING where the cast needs it, or a clear error when the backend cannot convert;
a nullability change becomes SET/DROP NOT NULL;
a default change becomes SET/DROP DEFAULT;
a comment change becomes COMMENT ON COLUMN, with the core-type marker kept, so describe() still round-trips.
Repositioning a column has no PostgreSQL equivalent; it is already skipped there (supports_column_position).
Activity