3232
3333from sqlglot import exp , select
3434from sqlglot .executor import execute
35+ from tenacity import retry , stop_after_attempt , wait_exponential , retry_if_not_exception_type
3536
3637from sqlmesh .core import constants as c
3738from sqlmesh .core import dialect as d
7677from sqlmesh .utils .errors import (
7778 ConfigError ,
7879 DestructiveChangeError ,
80+ MigrationNotSupportedError ,
7981 SQLMeshError ,
8082 format_destructive_change_msg ,
8183 format_additive_change_msg ,
@@ -492,7 +494,7 @@ def migrate(
492494 with self .concurrent_context ():
493495 # Only migrate snapshots for which there's an existing data object
494496 concurrent_apply_to_snapshots (
495- snapshots_by_name . values () ,
497+ target_snapshots ,
496498 lambda s : self ._migrate_snapshot (
497499 s ,
498500 snapshots_by_name ,
@@ -761,7 +763,7 @@ def _evaluate_snapshot(
761763 snapshots = snapshots ,
762764 deployability_index = deployability_index ,
763765 render_kwargs = create_render_kwargs ,
764- rendered_physical_properties = rendered_physical_properties ,
766+ rendered_physical_properties = rendered_physical_properties . copy () ,
765767 allow_destructive_snapshots = allow_destructive_snapshots ,
766768 allow_additive_snapshots = allow_additive_snapshots ,
767769 )
@@ -774,7 +776,7 @@ def _evaluate_snapshot(
774776 is_table_deployable = is_snapshot_deployable ,
775777 deployability_index = deployability_index ,
776778 create_render_kwargs = create_render_kwargs ,
777- rendered_physical_properties = rendered_physical_properties ,
779+ rendered_physical_properties = rendered_physical_properties . copy () ,
778780 dry_run = False ,
779781 run_pre_post_statements = False ,
780782 )
@@ -865,6 +867,7 @@ def create_snapshot(
865867 rendered_physical_properties = rendered_physical_properties ,
866868 allow_destructive_snapshots = allow_destructive_snapshots ,
867869 allow_additive_snapshots = allow_additive_snapshots ,
870+ run_pre_post_statements = True ,
868871 )
869872 else :
870873 is_table_deployable = deployability_index .is_deployable (snapshot )
@@ -1024,6 +1027,7 @@ def _clone_snapshot_in_dev(
10241027 rendered_physical_properties : t .Dict [str , exp .Expression ],
10251028 allow_destructive_snapshots : t .Set [str ],
10261029 allow_additive_snapshots : t .Set [str ],
1030+ run_pre_post_statements : bool = False ,
10271031 ) -> None :
10281032 adapter = self .get_adapter (snapshot .model .gateway )
10291033
@@ -1035,7 +1039,6 @@ def _clone_snapshot_in_dev(
10351039 adapter .clone_table (
10361040 target_table_name ,
10371041 snapshot .table_name (),
1038- replace = True ,
10391042 rendered_physical_properties = rendered_physical_properties ,
10401043 )
10411044 self ._migrate_target_table (
@@ -1047,6 +1050,7 @@ def _clone_snapshot_in_dev(
10471050 rendered_physical_properties = rendered_physical_properties ,
10481051 allow_destructive_snapshots = allow_destructive_snapshots ,
10491052 allow_additive_snapshots = allow_additive_snapshots ,
1053+ run_pre_post_statements = run_pre_post_statements ,
10501054 )
10511055 except Exception :
10521056 adapter .drop_table (target_table_name )
@@ -1111,6 +1115,15 @@ def _migrate_snapshot(
11111115 dry_run = True ,
11121116 )
11131117
1118+ # Retry in case when the table is migrated concurrently from another plan application
1119+ @retry (
1120+ reraise = True ,
1121+ stop = stop_after_attempt (5 ),
1122+ wait = wait_exponential (min = 1 , max = 16 ),
1123+ retry = retry_if_not_exception_type (
1124+ (DestructiveChangeError , AdditiveChangeError , MigrationNotSupportedError )
1125+ ),
1126+ )
11141127 def _migrate_target_table (
11151128 self ,
11161129 target_table_name : str ,
@@ -1440,8 +1453,9 @@ def _can_clone(self, snapshot: Snapshot, deployability_index: DeployabilityIndex
14401453 and adapter .SUPPORTS_CLONING
14411454 # managed models cannot have their schema mutated because theyre based on queries, so clone + alter wont work
14421455 and not snapshot .is_managed
1443- # If the deployable table is missing we can't clone it
14441456 and not deployability_index .is_deployable (snapshot )
1457+ # If the deployable table is missing we can't clone it
1458+ and adapter .table_exists (snapshot .table_name ())
14451459 )
14461460
14471461 def _get_data_objects (
@@ -2671,7 +2685,7 @@ def migrate(
26712685 )
26722686 if len (potential_alter_operations ) > 0 :
26732687 # this can happen if a user changes a managed model and deliberately overrides a plan to be forward only, eg `sqlmesh plan --forward-only`
2674- raise SQLMeshError (
2688+ raise MigrationNotSupportedError (
26752689 f"The schema of the managed model '{ target_table_name } ' cannot be updated in a forward-only fashion."
26762690 )
26772691
0 commit comments