@@ -878,6 +878,7 @@ def create_snapshot(
878878 deployability_index = deployability_index ,
879879 create_render_kwargs = create_render_kwargs ,
880880 rendered_physical_properties = rendered_physical_properties ,
881+ skip_grants = True ,
881882 dry_run = True ,
882883 )
883884
@@ -1436,12 +1437,12 @@ def _execute_create(
14361437 table_name = table_name ,
14371438 model = snapshot .model ,
14381439 is_table_deployable = is_table_deployable ,
1440+ skip_grants = skip_grants ,
14391441 render_kwargs = create_render_kwargs ,
14401442 is_snapshot_deployable = is_snapshot_deployable ,
14411443 is_snapshot_representative = is_snapshot_representative ,
14421444 dry_run = dry_run ,
14431445 physical_properties = rendered_physical_properties ,
1444- skip_grants = skip_grants ,
14451446 )
14461447 if run_pre_post_statements :
14471448 adapter .execute (snapshot .model .render_post_statements (** create_render_kwargs ))
@@ -1606,6 +1607,7 @@ def create(
16061607 model : Model ,
16071608 is_table_deployable : bool ,
16081609 render_kwargs : t .Dict [str , t .Any ],
1610+ skip_grants : bool ,
16091611 ** kwargs : t .Any ,
16101612 ) -> None :
16111613 """Creates the target table or view.
@@ -1749,6 +1751,7 @@ def create(
17491751 model : Model ,
17501752 is_table_deployable : bool ,
17511753 render_kwargs : t .Dict [str , t .Any ],
1754+ skip_grants : bool ,
17521755 ** kwargs : t .Any ,
17531756 ) -> None :
17541757 pass
@@ -1824,10 +1827,10 @@ def promote(
18241827 view_properties = model .render_virtual_properties (** render_kwargs ),
18251828 )
18261829
1827- # Apply grants to the physical layer table
1830+ # Apply grants to the physical layer (referenced table / view) after promotion
18281831 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18291832
1830- # Apply grants to the virtual layer view
1833+ # Apply grants to the virtual layer ( view) after promotion
18311834 self ._apply_grants (model , view_name , GrantsTargetLayer .VIRTUAL )
18321835
18331836 def demote (self , view_name : str , ** kwargs : t .Any ) -> None :
@@ -1842,6 +1845,7 @@ def create(
18421845 model : Model ,
18431846 is_table_deployable : bool ,
18441847 render_kwargs : t .Dict [str , t .Any ],
1848+ skip_grants : bool ,
18451849 ** kwargs : t .Any ,
18461850 ) -> None :
18471851 ctas_query = model .ctas_query (** render_kwargs )
@@ -1887,7 +1891,7 @@ def create(
18871891 )
18881892
18891893 # Apply grants after table creation (unless explicitly skipped by caller)
1890- if not kwargs . get ( " skip_grants" , False ) :
1894+ if not skip_grants :
18911895 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18921896
18931897 def migrate (
@@ -1929,6 +1933,7 @@ def _replace_query_for_model(
19291933 name : str ,
19301934 query_or_df : QueryOrDF ,
19311935 render_kwargs : t .Dict [str , t .Any ],
1936+ skip_grants : bool = False ,
19321937 ** kwargs : t .Any ,
19331938 ) -> None :
19341939 """Replaces the table for the given model.
@@ -1966,7 +1971,7 @@ def _replace_query_for_model(
19661971 )
19671972
19681973 # Apply grants after table replacement (unless explicitly skipped by caller)
1969- if not kwargs . get ( " skip_grants" , False ) :
1974+ if not skip_grants :
19701975 self ._apply_grants (model , name , GrantsTargetLayer .PHYSICAL )
19711976
19721977 def _get_target_and_source_columns (
@@ -2216,6 +2221,7 @@ def create(
22162221 model : Model ,
22172222 is_table_deployable : bool ,
22182223 render_kwargs : t .Dict [str , t .Any ],
2224+ skip_grants : bool ,
22192225 ** kwargs : t .Any ,
22202226 ) -> None :
22212227 model = t .cast (SeedModel , model )
@@ -2229,29 +2235,38 @@ def create(
22292235 )
22302236 return
22312237
2232- # Skip grants in parent create call since we'll apply them after data insertion
2233- kwargs_no_grants = {** kwargs }
2234- kwargs_no_grants ["skip_grants" ] = True
2235-
2236- super ().create (table_name , model , is_table_deployable , render_kwargs , ** kwargs_no_grants )
2238+ super ().create (
2239+ table_name ,
2240+ model ,
2241+ is_table_deployable ,
2242+ render_kwargs ,
2243+ skip_grants = True , # Skip grants; they're applied after data insertion
2244+ ** kwargs ,
2245+ )
22372246 # For seeds we insert data at the time of table creation.
22382247 try :
22392248 for index , df in enumerate (model .render_seed ()):
22402249 if index == 0 :
22412250 self ._replace_query_for_model (
2242- model , table_name , df , render_kwargs , ** kwargs_no_grants
2251+ model ,
2252+ table_name ,
2253+ df ,
2254+ render_kwargs ,
2255+ skip_grants = True , # Skip grants; they're applied after data insertion
2256+ ** kwargs ,
22432257 )
22442258 else :
22452259 self .adapter .insert_append (
22462260 table_name , df , target_columns_to_types = model .columns_to_types
22472261 )
2262+
2263+ if not skip_grants :
2264+ # Apply grants after seed table creation and data insertion
2265+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
22482266 except Exception :
22492267 self .adapter .drop_table (table_name )
22502268 raise
22512269
2252- # Apply grants after seed table creation or data insertion
2253- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2254-
22552270 def insert (
22562271 self ,
22572272 table_name : str ,
@@ -2283,6 +2298,7 @@ def create(
22832298 model : Model ,
22842299 is_table_deployable : bool ,
22852300 render_kwargs : t .Dict [str , t .Any ],
2301+ skip_grants : bool ,
22862302 ** kwargs : t .Any ,
22872303 ) -> None :
22882304 assert isinstance (model .kind , (SCDType2ByTimeKind , SCDType2ByColumnKind ))
@@ -2312,11 +2328,13 @@ def create(
23122328 model ,
23132329 is_table_deployable ,
23142330 render_kwargs ,
2331+ skip_grants ,
23152332 ** kwargs ,
23162333 )
23172334
2318- # Apply grants after SCD Type 2 table creation
2319- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2335+ if not skip_grants :
2336+ # Apply grants after SCD Type 2 table creation
2337+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
23202338
23212339 def insert (
23222340 self ,
@@ -2460,14 +2478,17 @@ def create(
24602478 model : Model ,
24612479 is_table_deployable : bool ,
24622480 render_kwargs : t .Dict [str , t .Any ],
2481+ skip_grants : bool ,
24632482 ** kwargs : t .Any ,
24642483 ) -> None :
24652484 if self .adapter .table_exists (table_name ):
24662485 # Make sure we don't recreate the view to prevent deletion of downstream views in engines with no late
24672486 # binding support (because of DROP CASCADE).
24682487 logger .info ("View '%s' already exists" , table_name )
2469- # Always apply grants when present, even if view exists, to handle grants updates
2470- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2488+
2489+ if not skip_grants :
2490+ # Always apply grants when present, even if view exists, to handle grants updates
2491+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24712492 return
24722493
24732494 logger .info ("Creating view '%s'" , table_name )
@@ -2491,8 +2512,9 @@ def create(
24912512 column_descriptions = model .column_descriptions if is_table_deployable else None ,
24922513 )
24932514
2494- # Apply grants after view creation
2495- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2515+ if not skip_grants :
2516+ # Apply grants after view creation
2517+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24962518
24972519 def migrate (
24982520 self ,
@@ -2669,6 +2691,7 @@ def create(
26692691 model : Model ,
26702692 is_table_deployable : bool ,
26712693 render_kwargs : t .Dict [str , t .Any ],
2694+ skip_grants : bool ,
26722695 ** kwargs : t .Any ,
26732696 ) -> None :
26742697 is_snapshot_deployable : bool = kwargs ["is_snapshot_deployable" ]
@@ -2689,24 +2712,21 @@ def create(
26892712 )
26902713
26912714 # Apply grants after managed table creation
2692- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2715+ if not skip_grants :
2716+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
26932717
26942718 elif not is_table_deployable :
26952719 # Only create the dev preview table as a normal table.
26962720 # For the main table, if the snapshot is cant be deployed to prod (eg upstream is forward-only) do nothing.
26972721 # Any downstream models that reference it will be updated to point to the dev preview table.
26982722 # If the user eventually tries to deploy it, the logic in insert() will see it doesnt exist and create it
2699-
2700- # Create preview table but don't apply grants here since the table is not deployable
2701- # Grants will be applied later when the table becomes deployable
2702- kwargs_no_grants = {** kwargs }
2703- kwargs_no_grants ["skip_grants" ] = True
27042723 super ().create (
27052724 table_name = table_name ,
27062725 model = model ,
27072726 is_table_deployable = is_table_deployable ,
27082727 render_kwargs = render_kwargs ,
2709- ** kwargs_no_grants ,
2728+ skip_grants = skip_grants ,
2729+ ** kwargs ,
27102730 )
27112731
27122732 def insert (
@@ -2733,6 +2753,7 @@ def insert(
27332753 column_descriptions = model .column_descriptions ,
27342754 table_format = model .table_format ,
27352755 )
2756+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
27362757 elif not is_snapshot_deployable :
27372758 # Snapshot isnt deployable; update the preview table instead
27382759 # If the snapshot was deployable, then data would have already been loaded in create() because a managed table would have been created
@@ -2782,7 +2803,7 @@ def migrate(
27822803 )
27832804
27842805 # Apply grants after verifying no schema changes
2785- # This ensures metadata-only changes ( grants) are applied
2806+ # This ensures metadata-only grants changes are applied
27862807 self ._apply_grants (snapshot .model , target_table_name , GrantsTargetLayer .PHYSICAL )
27872808
27882809 def delete (self , name : str , ** kwargs : t .Any ) -> None :
0 commit comments