Add common database backend support for changing field types.
Review Request #12232 — Created April 8, 2022 and submitted — Latest diff uploaded
This introduces new methods on
BaseEvolutionOperations
for changing a
field type:
-
change_column_type()
: Orchestrates changing the type of a field,
dropping/re-adding any constraints and updating the types of any
fields pointing to the changed field. -
get_change_column_type_sql()
: Returns backend-specific SQL for
changing the type of any given field.
Along with a new capability attribute, change_column_type_sets_attrs
,
which states whether get_change_column_type_sql()
will also handle
setting all the attributes for the field definition. If False
,
attributes need to be set in a separate change_column_attrs()
call.
The basic strategy for changing a field type is:
-
Any constraints pointing to the changed field must be dropped, in
order to avoid issues with incompatible data types between the
referring fields and the changed field. -
The field type can then safely be changed. Depending on the database
backend, the command for this may include the entire field definition
(NOT NULL
,VARCHAR(...)
, etc.), or it may not (requiring that
these changes are made separately, if needed). This part is not
currently implemented by any backends. -
Any fields referring to the changed field need to be updated to match
the field type. -
Constraints dropped in step 1 can then be restored.
BaseEvolutionOperations
takes care of all of this by default, leaving
most backends responsible only for the capability attribute and the
implementation of get_change_column_type_sql()
. Subclasses are free
to override the entire process, if needed.
Upcoming changes will implement the per-database support, the
orchestration in ChangeField
and related objects, and the test suite.
Tested along with the other upcoming changes for this feature. All unit
tests pass on all supported databases and versions of Django.