From 66e8da373f24e41ce0f8fd7b1fcafb93933dabef Mon Sep 17 00:00:00 2001 From: Jeremy McCormick Date: Thu, 29 Jan 2026 12:56:54 -0600 Subject: [PATCH 1/2] Fix issue with attribute copying from column ref overrides Using `model_dump` was causing conversion to JSON types here, so the `datatype` attribute was being assigned a `str` object and not a `StrEnum`, which broke code attempting to use the field as an enum. Copying the attributes directly fixes this issue, as it preserves the Python types at runtime and avoids the conversion. --- python/felis/datamodel.py | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/python/felis/datamodel.py b/python/felis/datamodel.py index f3053f41..1a36008f 100644 --- a/python/felis/datamodel.py +++ b/python/felis/datamodel.py @@ -1331,8 +1331,24 @@ def _dereference_resource_columns(self: Schema, info: ValidationInfo) -> Schema: table.column_refs = {} return self + @classmethod + def _copy_overrides_to_column( + cls, column_ref: ColumnResourceRef, column_copy: Column + ) -> ColumnOverrides | None: + """Copy overrides from a column ref to a column.""" + if column_ref.overrides is not None: + overrides = column_ref.overrides + override_fields = overrides.model_fields_set + for field_name in override_fields: + if hasattr(column_copy, field_name): + # Use attribute assignment to avoid type conversion issues + # which can occur with using model_dump and model_copy + setattr(column_copy, field_name, getattr(overrides, field_name)) + return column_ref.overrides + + @classmethod def _process_column_refs( - self, + cls, table: Table, ref_tables: ResourceTableMap, resource_schema: Schema, @@ -1340,7 +1356,7 @@ def _process_column_refs( column_ref_index_increment: int | None = None, ) -> None: """Process column references from an external resource and add them - to the given table. + to the given table as columns. """ current_column_index = column_ref_index_increment if column_ref_index_increment is not None else -1 @@ -1392,11 +1408,8 @@ def _process_column_refs( # Apply overrides to the original column definition overrides: ColumnOverrides | None = None - if column_ref is not None and column_ref.overrides is not None: - overrides = column_ref.overrides - for field_name, override_value in overrides.model_dump().items(): - if override_value is not None: - setattr(column_copy, field_name, override_value) + if column_ref is not None: + overrides = cls._copy_overrides_to_column(column_ref, column_copy) # Manually set the ID of the copied column as ID generation has # already occurred by now From 72dae4528c28a3b0e4da42e41b4a8c18b7bc8c8d Mon Sep 17 00:00:00 2001 From: Jeremy McCormick Date: Thu, 29 Jan 2026 16:06:41 -0600 Subject: [PATCH 2/2] Add news fragment --- docs/changes/DM-53979.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/changes/DM-53979.bugfix.rst diff --git a/docs/changes/DM-53979.bugfix.rst b/docs/changes/DM-53979.bugfix.rst new file mode 100644 index 00000000..49eb62c7 --- /dev/null +++ b/docs/changes/DM-53979.bugfix.rst @@ -0,0 +1 @@ +Fixed an issue when copying column ref overrides to the target column