|
18 | 18 | from sqlmesh import Config, Context
|
19 | 19 | from sqlmesh.cli.example_project import init_example_project
|
20 | 20 | from sqlmesh.core.config import load_config_from_paths
|
| 21 | +from sqlmesh.core.config.connection import ConnectionConfig |
21 | 22 | import sqlmesh.core.dialect as d
|
22 | 23 | from sqlmesh.core.dialect import select_from_values
|
23 | 24 | from sqlmesh.core.model import Model, load_sql_based_model
|
24 | 25 | from sqlmesh.core.engine_adapter.shared import DataObject, DataObjectType
|
25 | 26 | from sqlmesh.core.engine_adapter.mixins import RowDiffMixin
|
26 | 27 | from sqlmesh.core.model.definition import create_sql_model
|
27 | 28 | from sqlmesh.core.plan import Plan
|
| 29 | +from sqlmesh.core.state_sync.db import EngineAdapterStateSync |
28 | 30 | from sqlmesh.core.snapshot import Snapshot, SnapshotChangeCategory
|
29 | 31 | from sqlmesh.utils.date import now, to_date, to_time_column
|
30 | 32 | from sqlmesh.core.table_diff import TableDiff
|
@@ -2667,3 +2669,37 @@ def test_table_diff_identical_dataset(ctx: TestContext):
|
2667 | 2669 | assert row_diff.stats["t_only_count"] == 0
|
2668 | 2670 | assert row_diff.s_sample.shape == (0, 3)
|
2669 | 2671 | assert row_diff.t_sample.shape == (0, 3)
|
| 2672 | + |
| 2673 | + |
| 2674 | +def test_state_migrate_from_scratch(ctx: TestContext): |
| 2675 | + if ctx.test_type != "query": |
| 2676 | + pytest.skip("state migration tests are only relevant for query") |
| 2677 | + |
| 2678 | + test_schema = ctx.add_test_suffix("state") |
| 2679 | + ctx._schemas.append(test_schema) # so it gets cleaned up when the test finishes |
| 2680 | + |
| 2681 | + def _use_warehouse_as_state_connection(gateway_name: str, config: Config): |
| 2682 | + warehouse_connection = config.gateways[gateway_name].connection |
| 2683 | + assert isinstance(warehouse_connection, ConnectionConfig) |
| 2684 | + if warehouse_connection.is_forbidden_for_state_sync: |
| 2685 | + pytest.skip( |
| 2686 | + f"{warehouse_connection.type_} doesnt support being used as a state connection" |
| 2687 | + ) |
| 2688 | + |
| 2689 | + # this triggers the fallback to using the warehouse as a state connection |
| 2690 | + config.gateways[gateway_name].state_connection = None |
| 2691 | + assert config.get_state_connection(gateway_name) is None |
| 2692 | + |
| 2693 | + config.gateways[gateway_name].state_schema = test_schema |
| 2694 | + |
| 2695 | + sqlmesh_context = ctx.create_context(config_mutator=_use_warehouse_as_state_connection) |
| 2696 | + assert sqlmesh_context.config.get_state_schema(ctx.gateway) == test_schema |
| 2697 | + |
| 2698 | + state_sync = ( |
| 2699 | + sqlmesh_context._new_state_sync() |
| 2700 | + ) # this prevents migrate() being called which it does if you access the state_sync property |
| 2701 | + assert isinstance(state_sync, EngineAdapterStateSync) |
| 2702 | + assert state_sync.engine_adapter.dialect == ctx.dialect |
| 2703 | + |
| 2704 | + # will throw if one of the migrations produces an error, which can happen if we forget to take quoting or normalization into account |
| 2705 | + sqlmesh_context.migrate() |
0 commit comments