@@ -384,6 +384,14 @@ def _delete_deferred_unique_indexes_for_field(self, field):
384384 def _add_deferred_unique_index_for_field (self , field , statement ):
385385 self ._deferred_unique_indexes [str (field )].append (statement )
386386
387+ def _column_generated_sql (self , field ):
388+ """Return the SQL to use in a GENERATED ALWAYS clause."""
389+ expression_sql , params = field .generated_sql (self .connection )
390+ persistency_sql = "PERSISTED" if field .db_persist else ""
391+ if params :
392+ expression_sql = expression_sql % tuple (self .quote_value (p ) for p in params )
393+ return f"AS { expression_sql } { persistency_sql } "
394+
387395 def _alter_field (self , model , old_field , new_field , old_type , new_type ,
388396 old_db_params , new_db_params , strict = False ):
389397 """Actually perform a "physical" (non-ManyToMany) field update."""
@@ -1016,6 +1024,9 @@ def add_field(self, model, field):
10161024 # It might not actually have a column behind it
10171025 if definition is None :
10181026 return
1027+ # Remove column type from definition if field is generated
1028+ if (django_version >= (5 ,0 ) and field .generated ):
1029+ definition = definition [definition .find ('AS' ):]
10191030 # Nullable columns with default values require 'WITH VALUES' to set existing rows
10201031 if 'DEFAULT' in definition and field .null :
10211032 definition = definition .replace ('NULL' , 'WITH VALUES' )
@@ -1218,6 +1229,9 @@ def create_model(self, model):
12181229 definition , extra_params = self .column_sql (model , field )
12191230 if definition is None :
12201231 continue
1232+ # Remove column type from definition if field is generated
1233+ if (django_version >= (5 ,0 ) and field .generated ):
1234+ definition = definition [definition .find ('AS' ):]
12211235
12221236 if (self .connection .features .supports_nullable_unique_constraints and
12231237 not field .many_to_many and field .null and field .unique ):
0 commit comments