diff --git a/django_snowflake/features.py b/django_snowflake/features.py index 9ca7023..49e4528 100644 --- a/django_snowflake/features.py +++ b/django_snowflake/features.py @@ -57,6 +57,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_transactions = False # This feature is specific to the Django fork used for testing. supports_tz_offsets = False + supports_virtual_generated_columns = True uses_savepoints = False ignores_table_name_case = True test_collations = { @@ -67,6 +68,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): 'cs': None, 'non_default': 'en-ci', 'swedish_ci': 'sv-ci', + 'virtual': None, } test_now_utc_template = 'SYSDATE()' diff --git a/django_snowflake/schema.py b/django_snowflake/schema.py index 63f38de..f66e284 100644 --- a/django_snowflake/schema.py +++ b/django_snowflake/schema.py @@ -95,6 +95,8 @@ def column_sql(self, model, field, include_default=False, exclude_not_null=False collation = db_params.get('collation') if collation: sql += self._collate_sql(collation) + if field.generated: + sql += self._column_generated_sql(field) if not field.null and not exclude_not_null: sql += " NOT NULL" # Add database default. @@ -158,6 +160,13 @@ def _alter_field(self, model, old_field, new_field, old_type, new_type, }, }) + def _column_generated_sql(self, field): + """Return the SQL to use in a GENERATED ALWAYS clause.""" + expression_sql, params = field.generated_sql(self.connection) + if params: + expression_sql = expression_sql % tuple(self.quote_value(p) for p in params) + return f" AS ({expression_sql})" + def quote_value(self, value): if isinstance(value, str): return "'%s'" % value.replace("'", "\\'")