@@ -880,6 +880,7 @@ def create_snapshot(
880880 deployability_index = deployability_index ,
881881 create_render_kwargs = create_render_kwargs ,
882882 rendered_physical_properties = rendered_physical_properties ,
883+ skip_grants = True ,
883884 dry_run = True ,
884885 )
885886
@@ -1440,12 +1441,12 @@ def _execute_create(
14401441 table_name = table_name ,
14411442 model = snapshot .model ,
14421443 is_table_deployable = is_table_deployable ,
1444+ skip_grants = skip_grants ,
14431445 render_kwargs = create_render_kwargs ,
14441446 is_snapshot_deployable = is_snapshot_deployable ,
14451447 is_snapshot_representative = is_snapshot_representative ,
14461448 dry_run = dry_run ,
14471449 physical_properties = rendered_physical_properties ,
1448- skip_grants = skip_grants ,
14491450 )
14501451 if run_pre_post_statements :
14511452 adapter .execute (snapshot .model .render_post_statements (** create_render_kwargs ))
@@ -1610,6 +1611,7 @@ def create(
16101611 model : Model ,
16111612 is_table_deployable : bool ,
16121613 render_kwargs : t .Dict [str , t .Any ],
1614+ skip_grants : bool ,
16131615 ** kwargs : t .Any ,
16141616 ) -> None :
16151617 """Creates the target table or view.
@@ -1753,6 +1755,7 @@ def create(
17531755 model : Model ,
17541756 is_table_deployable : bool ,
17551757 render_kwargs : t .Dict [str , t .Any ],
1758+ skip_grants : bool ,
17561759 ** kwargs : t .Any ,
17571760 ) -> None :
17581761 pass
@@ -1828,10 +1831,10 @@ def promote(
18281831 view_properties = model .render_virtual_properties (** render_kwargs ),
18291832 )
18301833
1831- # Apply grants to the physical layer table
1834+ # Apply grants to the physical layer (referenced table / view) after promotion
18321835 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18331836
1834- # Apply grants to the virtual layer view
1837+ # Apply grants to the virtual layer ( view) after promotion
18351838 self ._apply_grants (model , view_name , GrantsTargetLayer .VIRTUAL )
18361839
18371840 def demote (self , view_name : str , ** kwargs : t .Any ) -> None :
@@ -1846,6 +1849,7 @@ def create(
18461849 model : Model ,
18471850 is_table_deployable : bool ,
18481851 render_kwargs : t .Dict [str , t .Any ],
1852+ skip_grants : bool ,
18491853 ** kwargs : t .Any ,
18501854 ) -> None :
18511855 ctas_query = model .ctas_query (** render_kwargs )
@@ -1891,7 +1895,7 @@ def create(
18911895 )
18921896
18931897 # Apply grants after table creation (unless explicitly skipped by caller)
1894- if not kwargs . get ( " skip_grants" , False ) :
1898+ if not skip_grants :
18951899 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18961900
18971901 def migrate (
@@ -1933,6 +1937,7 @@ def _replace_query_for_model(
19331937 name : str ,
19341938 query_or_df : QueryOrDF ,
19351939 render_kwargs : t .Dict [str , t .Any ],
1940+ skip_grants : bool = False ,
19361941 ** kwargs : t .Any ,
19371942 ) -> None :
19381943 """Replaces the table for the given model.
@@ -1970,7 +1975,7 @@ def _replace_query_for_model(
19701975 )
19711976
19721977 # Apply grants after table replacement (unless explicitly skipped by caller)
1973- if not kwargs . get ( " skip_grants" , False ) :
1978+ if not skip_grants :
19741979 self ._apply_grants (model , name , GrantsTargetLayer .PHYSICAL )
19751980
19761981 def _get_target_and_source_columns (
@@ -2220,6 +2225,7 @@ def create(
22202225 model : Model ,
22212226 is_table_deployable : bool ,
22222227 render_kwargs : t .Dict [str , t .Any ],
2228+ skip_grants : bool ,
22232229 ** kwargs : t .Any ,
22242230 ) -> None :
22252231 model = t .cast (SeedModel , model )
@@ -2233,29 +2239,38 @@ def create(
22332239 )
22342240 return
22352241
2236- # Skip grants in parent create call since we'll apply them after data insertion
2237- kwargs_no_grants = {** kwargs }
2238- kwargs_no_grants ["skip_grants" ] = True
2239-
2240- super ().create (table_name , model , is_table_deployable , render_kwargs , ** kwargs_no_grants )
2242+ super ().create (
2243+ table_name ,
2244+ model ,
2245+ is_table_deployable ,
2246+ render_kwargs ,
2247+ skip_grants = True , # Skip grants; they're applied after data insertion
2248+ ** kwargs ,
2249+ )
22412250 # For seeds we insert data at the time of table creation.
22422251 try :
22432252 for index , df in enumerate (model .render_seed ()):
22442253 if index == 0 :
22452254 self ._replace_query_for_model (
2246- model , table_name , df , render_kwargs , ** kwargs_no_grants
2255+ model ,
2256+ table_name ,
2257+ df ,
2258+ render_kwargs ,
2259+ skip_grants = True , # Skip grants; they're applied after data insertion
2260+ ** kwargs ,
22472261 )
22482262 else :
22492263 self .adapter .insert_append (
22502264 table_name , df , target_columns_to_types = model .columns_to_types
22512265 )
2266+
2267+ if not skip_grants :
2268+ # Apply grants after seed table creation and data insertion
2269+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
22522270 except Exception :
22532271 self .adapter .drop_table (table_name )
22542272 raise
22552273
2256- # Apply grants after seed table creation or data insertion
2257- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2258-
22592274 def insert (
22602275 self ,
22612276 table_name : str ,
@@ -2287,6 +2302,7 @@ def create(
22872302 model : Model ,
22882303 is_table_deployable : bool ,
22892304 render_kwargs : t .Dict [str , t .Any ],
2305+ skip_grants : bool ,
22902306 ** kwargs : t .Any ,
22912307 ) -> None :
22922308 assert isinstance (model .kind , (SCDType2ByTimeKind , SCDType2ByColumnKind ))
@@ -2316,11 +2332,13 @@ def create(
23162332 model ,
23172333 is_table_deployable ,
23182334 render_kwargs ,
2335+ skip_grants ,
23192336 ** kwargs ,
23202337 )
23212338
2322- # Apply grants after SCD Type 2 table creation
2323- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2339+ if not skip_grants :
2340+ # Apply grants after SCD Type 2 table creation
2341+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
23242342
23252343 def insert (
23262344 self ,
@@ -2464,14 +2482,17 @@ def create(
24642482 model : Model ,
24652483 is_table_deployable : bool ,
24662484 render_kwargs : t .Dict [str , t .Any ],
2485+ skip_grants : bool ,
24672486 ** kwargs : t .Any ,
24682487 ) -> None :
24692488 if self .adapter .table_exists (table_name ):
24702489 # Make sure we don't recreate the view to prevent deletion of downstream views in engines with no late
24712490 # binding support (because of DROP CASCADE).
24722491 logger .info ("View '%s' already exists" , table_name )
2473- # Always apply grants when present, even if view exists, to handle grants updates
2474- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2492+
2493+ if not skip_grants :
2494+ # Always apply grants when present, even if view exists, to handle grants updates
2495+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24752496 return
24762497
24772498 logger .info ("Creating view '%s'" , table_name )
@@ -2495,8 +2516,9 @@ def create(
24952516 column_descriptions = model .column_descriptions if is_table_deployable else None ,
24962517 )
24972518
2498- # Apply grants after view creation
2499- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2519+ if not skip_grants :
2520+ # Apply grants after view creation
2521+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
25002522
25012523 def migrate (
25022524 self ,
@@ -2673,6 +2695,7 @@ def create(
26732695 model : Model ,
26742696 is_table_deployable : bool ,
26752697 render_kwargs : t .Dict [str , t .Any ],
2698+ skip_grants : bool ,
26762699 ** kwargs : t .Any ,
26772700 ) -> None :
26782701 is_snapshot_deployable : bool = kwargs ["is_snapshot_deployable" ]
@@ -2693,24 +2716,21 @@ def create(
26932716 )
26942717
26952718 # Apply grants after managed table creation
2696- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2719+ if not skip_grants :
2720+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
26972721
26982722 elif not is_table_deployable :
26992723 # Only create the dev preview table as a normal table.
27002724 # For the main table, if the snapshot is cant be deployed to prod (eg upstream is forward-only) do nothing.
27012725 # Any downstream models that reference it will be updated to point to the dev preview table.
27022726 # If the user eventually tries to deploy it, the logic in insert() will see it doesnt exist and create it
2703-
2704- # Create preview table but don't apply grants here since the table is not deployable
2705- # Grants will be applied later when the table becomes deployable
2706- kwargs_no_grants = {** kwargs }
2707- kwargs_no_grants ["skip_grants" ] = True
27082727 super ().create (
27092728 table_name = table_name ,
27102729 model = model ,
27112730 is_table_deployable = is_table_deployable ,
27122731 render_kwargs = render_kwargs ,
2713- ** kwargs_no_grants ,
2732+ skip_grants = skip_grants ,
2733+ ** kwargs ,
27142734 )
27152735
27162736 def insert (
@@ -2737,6 +2757,7 @@ def insert(
27372757 column_descriptions = model .column_descriptions ,
27382758 table_format = model .table_format ,
27392759 )
2760+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
27402761 elif not is_snapshot_deployable :
27412762 # Snapshot isnt deployable; update the preview table instead
27422763 # If the snapshot was deployable, then data would have already been loaded in create() because a managed table would have been created
@@ -2786,7 +2807,7 @@ def migrate(
27862807 )
27872808
27882809 # Apply grants after verifying no schema changes
2789- # This ensures metadata-only changes ( grants) are applied
2810+ # This ensures metadata-only grants changes are applied
27902811 self ._apply_grants (snapshot .model , target_table_name , GrantsTargetLayer .PHYSICAL )
27912812
27922813 def delete (self , name : str , ** kwargs : t .Any ) -> None :
0 commit comments