Conversation
bd67ec2 to
23c4570
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for on_additive_change configuration to provide fine-grained control over schema changes in SQLMesh models. It introduces the ability to differentiate between destructive changes (dropping columns) and additive changes (adding columns), allowing users to configure different behaviors for each type of schema modification.
Key changes include:
- New
OnAdditiveChangeenum with ERROR, WARN, ALLOW, and IGNORE options - Enhanced dbt adapter to properly map
on_schema_changevalues to SQLMesh settings - Updated schema diff logic to distinguish additive changes and apply filtering based on IGNORE settings
Reviewed Changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| sqlmesh/core/model/kind.py | Adds OnAdditiveChange enum and integrates it into incremental model kinds |
| sqlmesh/dbt/model.py | Updates dbt adapter to map on_schema_change to both destructive and additive change settings |
| sqlmesh/core/schema_diff.py | Implements additive change detection and filtering logic with metadata support |
| sqlmesh/core/plan/builder.py | Adds additive change validation to plan building process |
| sqlmesh/core/snapshot/evaluator.py | Integrates additive change checking into snapshot evaluation |
| sqlmesh/utils/errors.py | Adds AdditiveChangeError and formatting functions for additive changes |
Comments suppressed due to low confidence (1)
tests/core/test_schema_diff.py:172
- [nitpick] The parameter name
is_part_of_destructive_changeis inconsistent with the attribute name used in the actual implementation. Consider renaming tois_destructivefor brevity and consistency.
dict(support_positional_add=True),
231257e to
c12ac90
Compare
c12ac90 to
19e794d
Compare
| ) | ||
| # Add current type metadata for additive classification | ||
| if self.current_type: | ||
| alter_column.meta["current_type"] = self.current_type |
There was a problem hiding this comment.
Do we use this anywhere?
| column.set("position", self.add_position.column_position_node) | ||
| # Set metadata if this ADD operation supports destructive changes | ||
| if self.is_part_of_destructive_change: | ||
| column.meta["sqlmesh_destructive"] = True |
There was a problem hiding this comment.
I don't understand why does it matter. There's will be a corresponding drop alteration which will trigger the check. Why complicate this?
There was a problem hiding this comment.
Can we just check whether the same column shows up for both drop and add alteration in the generated list? This will make it more explicit.
There was a problem hiding this comment.
Conceptually the reason why something like this is needed is because we can't assume ADD commands are additive - if they are ADD commands that are only needed due to a DROP command then we don't want that add either.
Doing it based on column name also works and I agree is cleaner since it wouldn't require creating metadata like this.
|
I believe we still need an empty migration script to recompute the metadata hash |
|
Deprecated by: #5193 All the feedback from this PR was address in the new PR. |
Breaking explanation: This change is breaking if you currently use the dbt adapter and have models using
on_schema_changewhere we used to not correctly mimic the behavior in the SQLMesh runtime. This is non-breaking for SQLMesh native users.In main, SQLMesh currently just detects destructive changes and allows users 3 different behavior options (ERROR, WARN, ALLOW). The problem is that dbt has schema change options that, in SQLMesh terms, differentiates destructive and additive changes. For example
append_new_columnsallows additive changes but ignores destructive changes. Furthermore they have anignoreoption which means that no schema changes are performed on tables.Therefore two fundamental changes are made in this PR:
on_additive_changeincremental property is added that behaves just likeon_destructive_changeexcept applies to additive changesignoreis added as an option toon_destructive_change. This should never really be used outside of some workaround edge-cases and documentation properly reflects this. dbt just says it will fail next time you run if you ignore (which is the default behavior)...The dbt adapter is updated to use these changes. See table below for a mapping of behavior from dbt -> SQLMesh (the docs also contain this):
on_schema_changeon_destructive_changeon_additive_changeTwo follow up PRs are required to reach
on_schema_changeparity:append_new_columnsignores alters even if the alters are additive. This PR would consider that additive and allow the change through. So need a way for dbt adapter to configure schema differ to consider alters destructive so it can be ignored.on_schema_changeonly tracks top-level column changes while, on some engines, SQLMesh tracks nested column changes. Therefore there needs to be a way to let dbt adapter to configure SQLMesh so it doesn't do nested changes.dbt documentation: https://docs.getdbt.com/docs/build/incremental-models#what-if-the-columns-of-my-incremental-model-change
TODO: