@@ -882,6 +882,7 @@ def create_snapshot(
882882 deployability_index = deployability_index ,
883883 create_render_kwargs = create_render_kwargs ,
884884 rendered_physical_properties = rendered_physical_properties ,
885+ skip_grants = True ,
885886 dry_run = True ,
886887 )
887888
@@ -1442,12 +1443,12 @@ def _execute_create(
14421443 table_name = table_name ,
14431444 model = snapshot .model ,
14441445 is_table_deployable = is_table_deployable ,
1446+ skip_grants = skip_grants ,
14451447 render_kwargs = create_render_kwargs ,
14461448 is_snapshot_deployable = is_snapshot_deployable ,
14471449 is_snapshot_representative = is_snapshot_representative ,
14481450 dry_run = dry_run ,
14491451 physical_properties = rendered_physical_properties ,
1450- skip_grants = skip_grants ,
14511452 )
14521453 if run_pre_post_statements :
14531454 adapter .execute (snapshot .model .render_post_statements (** create_render_kwargs ))
@@ -1612,6 +1613,7 @@ def create(
16121613 model : Model ,
16131614 is_table_deployable : bool ,
16141615 render_kwargs : t .Dict [str , t .Any ],
1616+ skip_grants : bool ,
16151617 ** kwargs : t .Any ,
16161618 ) -> None :
16171619 """Creates the target table or view.
@@ -1755,6 +1757,7 @@ def create(
17551757 model : Model ,
17561758 is_table_deployable : bool ,
17571759 render_kwargs : t .Dict [str , t .Any ],
1760+ skip_grants : bool ,
17581761 ** kwargs : t .Any ,
17591762 ) -> None :
17601763 pass
@@ -1830,10 +1833,10 @@ def promote(
18301833 view_properties = model .render_virtual_properties (** render_kwargs ),
18311834 )
18321835
1833- # Apply grants to the physical layer table
1836+ # Apply grants to the physical layer (referenced table / view) after promotion
18341837 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18351838
1836- # Apply grants to the virtual layer view
1839+ # Apply grants to the virtual layer ( view) after promotion
18371840 self ._apply_grants (model , view_name , GrantsTargetLayer .VIRTUAL )
18381841
18391842 def demote (self , view_name : str , ** kwargs : t .Any ) -> None :
@@ -1848,6 +1851,7 @@ def create(
18481851 model : Model ,
18491852 is_table_deployable : bool ,
18501853 render_kwargs : t .Dict [str , t .Any ],
1854+ skip_grants : bool ,
18511855 ** kwargs : t .Any ,
18521856 ) -> None :
18531857 ctas_query = model .ctas_query (** render_kwargs )
@@ -1893,7 +1897,7 @@ def create(
18931897 )
18941898
18951899 # Apply grants after table creation (unless explicitly skipped by caller)
1896- if not kwargs . get ( " skip_grants" , False ) :
1900+ if not skip_grants :
18971901 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18981902
18991903 def migrate (
@@ -1935,6 +1939,7 @@ def _replace_query_for_model(
19351939 name : str ,
19361940 query_or_df : QueryOrDF ,
19371941 render_kwargs : t .Dict [str , t .Any ],
1942+ skip_grants : bool = False ,
19381943 ** kwargs : t .Any ,
19391944 ) -> None :
19401945 """Replaces the table for the given model.
@@ -1972,7 +1977,7 @@ def _replace_query_for_model(
19721977 )
19731978
19741979 # Apply grants after table replacement (unless explicitly skipped by caller)
1975- if not kwargs . get ( " skip_grants" , False ) :
1980+ if not skip_grants :
19761981 self ._apply_grants (model , name , GrantsTargetLayer .PHYSICAL )
19771982
19781983 def _get_target_and_source_columns (
@@ -2222,6 +2227,7 @@ def create(
22222227 model : Model ,
22232228 is_table_deployable : bool ,
22242229 render_kwargs : t .Dict [str , t .Any ],
2230+ skip_grants : bool ,
22252231 ** kwargs : t .Any ,
22262232 ) -> None :
22272233 model = t .cast (SeedModel , model )
@@ -2235,29 +2241,38 @@ def create(
22352241 )
22362242 return
22372243
2238- # Skip grants in parent create call since we'll apply them after data insertion
2239- kwargs_no_grants = {** kwargs }
2240- kwargs_no_grants ["skip_grants" ] = True
2241-
2242- super ().create (table_name , model , is_table_deployable , render_kwargs , ** kwargs_no_grants )
2244+ super ().create (
2245+ table_name ,
2246+ model ,
2247+ is_table_deployable ,
2248+ render_kwargs ,
2249+ skip_grants = True , # Skip grants; they're applied after data insertion
2250+ ** kwargs ,
2251+ )
22432252 # For seeds we insert data at the time of table creation.
22442253 try :
22452254 for index , df in enumerate (model .render_seed ()):
22462255 if index == 0 :
22472256 self ._replace_query_for_model (
2248- model , table_name , df , render_kwargs , ** kwargs_no_grants
2257+ model ,
2258+ table_name ,
2259+ df ,
2260+ render_kwargs ,
2261+ skip_grants = True , # Skip grants; they're applied after data insertion
2262+ ** kwargs ,
22492263 )
22502264 else :
22512265 self .adapter .insert_append (
22522266 table_name , df , target_columns_to_types = model .columns_to_types
22532267 )
2268+
2269+ if not skip_grants :
2270+ # Apply grants after seed table creation and data insertion
2271+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
22542272 except Exception :
22552273 self .adapter .drop_table (table_name )
22562274 raise
22572275
2258- # Apply grants after seed table creation or data insertion
2259- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2260-
22612276 def insert (
22622277 self ,
22632278 table_name : str ,
@@ -2289,6 +2304,7 @@ def create(
22892304 model : Model ,
22902305 is_table_deployable : bool ,
22912306 render_kwargs : t .Dict [str , t .Any ],
2307+ skip_grants : bool ,
22922308 ** kwargs : t .Any ,
22932309 ) -> None :
22942310 assert isinstance (model .kind , (SCDType2ByTimeKind , SCDType2ByColumnKind ))
@@ -2318,11 +2334,13 @@ def create(
23182334 model ,
23192335 is_table_deployable ,
23202336 render_kwargs ,
2337+ skip_grants ,
23212338 ** kwargs ,
23222339 )
23232340
2324- # Apply grants after SCD Type 2 table creation
2325- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2341+ if not skip_grants :
2342+ # Apply grants after SCD Type 2 table creation
2343+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
23262344
23272345 def insert (
23282346 self ,
@@ -2466,14 +2484,17 @@ def create(
24662484 model : Model ,
24672485 is_table_deployable : bool ,
24682486 render_kwargs : t .Dict [str , t .Any ],
2487+ skip_grants : bool ,
24692488 ** kwargs : t .Any ,
24702489 ) -> None :
24712490 if self .adapter .table_exists (table_name ):
24722491 # Make sure we don't recreate the view to prevent deletion of downstream views in engines with no late
24732492 # binding support (because of DROP CASCADE).
24742493 logger .info ("View '%s' already exists" , table_name )
2475- # Always apply grants when present, even if view exists, to handle grants updates
2476- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2494+
2495+ if not skip_grants :
2496+ # Always apply grants when present, even if view exists, to handle grants updates
2497+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24772498 return
24782499
24792500 logger .info ("Creating view '%s'" , table_name )
@@ -2497,8 +2518,9 @@ def create(
24972518 column_descriptions = model .column_descriptions if is_table_deployable else None ,
24982519 )
24992520
2500- # Apply grants after view creation
2501- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2521+ if not skip_grants :
2522+ # Apply grants after view creation
2523+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
25022524
25032525 def migrate (
25042526 self ,
@@ -2675,6 +2697,7 @@ def create(
26752697 model : Model ,
26762698 is_table_deployable : bool ,
26772699 render_kwargs : t .Dict [str , t .Any ],
2700+ skip_grants : bool ,
26782701 ** kwargs : t .Any ,
26792702 ) -> None :
26802703 is_snapshot_deployable : bool = kwargs ["is_snapshot_deployable" ]
@@ -2695,24 +2718,21 @@ def create(
26952718 )
26962719
26972720 # Apply grants after managed table creation
2698- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2721+ if not skip_grants :
2722+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
26992723
27002724 elif not is_table_deployable :
27012725 # Only create the dev preview table as a normal table.
27022726 # For the main table, if the snapshot is cant be deployed to prod (eg upstream is forward-only) do nothing.
27032727 # Any downstream models that reference it will be updated to point to the dev preview table.
27042728 # If the user eventually tries to deploy it, the logic in insert() will see it doesnt exist and create it
2705-
2706- # Create preview table but don't apply grants here since the table is not deployable
2707- # Grants will be applied later when the table becomes deployable
2708- kwargs_no_grants = {** kwargs }
2709- kwargs_no_grants ["skip_grants" ] = True
27102729 super ().create (
27112730 table_name = table_name ,
27122731 model = model ,
27132732 is_table_deployable = is_table_deployable ,
27142733 render_kwargs = render_kwargs ,
2715- ** kwargs_no_grants ,
2734+ skip_grants = skip_grants ,
2735+ ** kwargs ,
27162736 )
27172737
27182738 def insert (
@@ -2739,6 +2759,7 @@ def insert(
27392759 column_descriptions = model .column_descriptions ,
27402760 table_format = model .table_format ,
27412761 )
2762+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
27422763 elif not is_snapshot_deployable :
27432764 # Snapshot isnt deployable; update the preview table instead
27442765 # If the snapshot was deployable, then data would have already been loaded in create() because a managed table would have been created
@@ -2788,7 +2809,7 @@ def migrate(
27882809 )
27892810
27902811 # Apply grants after verifying no schema changes
2791- # This ensures metadata-only changes ( grants) are applied
2812+ # This ensures metadata-only grants changes are applied
27922813 self ._apply_grants (snapshot .model , target_table_name , GrantsTargetLayer .PHYSICAL )
27932814
27942815 def delete (self , name : str , ** kwargs : t .Any ) -> None :
0 commit comments