@@ -888,6 +888,7 @@ def create_snapshot(
888888 deployability_index = deployability_index ,
889889 create_render_kwargs = create_render_kwargs ,
890890 rendered_physical_properties = rendered_physical_properties ,
891+ skip_grants = True ,
891892 dry_run = True ,
892893 )
893894
@@ -1450,12 +1451,12 @@ def _execute_create(
14501451 table_name = table_name ,
14511452 model = snapshot .model ,
14521453 is_table_deployable = is_table_deployable ,
1454+ skip_grants = skip_grants ,
14531455 render_kwargs = create_render_kwargs ,
14541456 is_snapshot_deployable = is_snapshot_deployable ,
14551457 is_snapshot_representative = is_snapshot_representative ,
14561458 dry_run = dry_run ,
14571459 physical_properties = rendered_physical_properties ,
1458- skip_grants = skip_grants ,
14591460 )
14601461 if run_pre_post_statements :
14611462 evaluation_strategy .run_post_statements (
@@ -1636,6 +1637,7 @@ def create(
16361637 model : Model ,
16371638 is_table_deployable : bool ,
16381639 render_kwargs : t .Dict [str , t .Any ],
1640+ skip_grants : bool ,
16391641 ** kwargs : t .Any ,
16401642 ) -> None :
16411643 """Creates the target table or view.
@@ -1797,6 +1799,7 @@ def create(
17971799 model : Model ,
17981800 is_table_deployable : bool ,
17991801 render_kwargs : t .Dict [str , t .Any ],
1802+ skip_grants : bool ,
18001803 ** kwargs : t .Any ,
18011804 ) -> None :
18021805 pass
@@ -1878,10 +1881,10 @@ def promote(
18781881 view_properties = model .render_virtual_properties (** render_kwargs ),
18791882 )
18801883
1881- # Apply grants to the physical layer table
1884+ # Apply grants to the physical layer (referenced table / view) after promotion
18821885 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18831886
1884- # Apply grants to the virtual layer view
1887+ # Apply grants to the virtual layer ( view) after promotion
18851888 self ._apply_grants (model , view_name , GrantsTargetLayer .VIRTUAL )
18861889
18871890 def demote (self , view_name : str , ** kwargs : t .Any ) -> None :
@@ -1902,6 +1905,7 @@ def create(
19021905 model : Model ,
19031906 is_table_deployable : bool ,
19041907 render_kwargs : t .Dict [str , t .Any ],
1908+ skip_grants : bool ,
19051909 ** kwargs : t .Any ,
19061910 ) -> None :
19071911 ctas_query = model .ctas_query (** render_kwargs )
@@ -1947,7 +1951,7 @@ def create(
19471951 )
19481952
19491953 # Apply grants after table creation (unless explicitly skipped by caller)
1950- if not kwargs . get ( " skip_grants" , False ) :
1954+ if not skip_grants :
19511955 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
19521956
19531957 def migrate (
@@ -1989,6 +1993,7 @@ def _replace_query_for_model(
19891993 name : str ,
19901994 query_or_df : QueryOrDF ,
19911995 render_kwargs : t .Dict [str , t .Any ],
1996+ skip_grants : bool = False ,
19921997 ** kwargs : t .Any ,
19931998 ) -> None :
19941999 """Replaces the table for the given model.
@@ -2026,7 +2031,7 @@ def _replace_query_for_model(
20262031 )
20272032
20282033 # Apply grants after table replacement (unless explicitly skipped by caller)
2029- if not kwargs . get ( " skip_grants" , False ) :
2034+ if not skip_grants :
20302035 self ._apply_grants (model , name , GrantsTargetLayer .PHYSICAL )
20312036
20322037 def _get_target_and_source_columns (
@@ -2276,6 +2281,7 @@ def create(
22762281 model : Model ,
22772282 is_table_deployable : bool ,
22782283 render_kwargs : t .Dict [str , t .Any ],
2284+ skip_grants : bool ,
22792285 ** kwargs : t .Any ,
22802286 ) -> None :
22812287 model = t .cast (SeedModel , model )
@@ -2289,22 +2295,34 @@ def create(
22892295 )
22902296 return
22912297
2292- # Skip grants in parent create call since we'll apply them after data insertion
2293- kwargs_no_grants = {** kwargs }
2294- kwargs_no_grants ["skip_grants" ] = True
2295-
2296- super ().create (table_name , model , is_table_deployable , render_kwargs , ** kwargs_no_grants )
2298+ super ().create (
2299+ table_name ,
2300+ model ,
2301+ is_table_deployable ,
2302+ render_kwargs ,
2303+ skip_grants = True , # Skip grants; they're applied after data insertion
2304+ ** kwargs ,
2305+ )
22972306 # For seeds we insert data at the time of table creation.
22982307 try :
22992308 for index , df in enumerate (model .render_seed ()):
23002309 if index == 0 :
23012310 self ._replace_query_for_model (
2302- model , table_name , df , render_kwargs , ** kwargs_no_grants
2311+ model ,
2312+ table_name ,
2313+ df ,
2314+ render_kwargs ,
2315+ skip_grants = True , # Skip grants; they're applied after data insertion
2316+ ** kwargs ,
23032317 )
23042318 else :
23052319 self .adapter .insert_append (
23062320 table_name , df , target_columns_to_types = model .columns_to_types
23072321 )
2322+
2323+ if not skip_grants :
2324+ # Apply grants after seed table creation and data insertion
2325+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
23082326 except Exception :
23092327 self .adapter .drop_table (table_name )
23102328 raise
@@ -2352,6 +2370,7 @@ def create(
23522370 model : Model ,
23532371 is_table_deployable : bool ,
23542372 render_kwargs : t .Dict [str , t .Any ],
2373+ skip_grants : bool ,
23552374 ** kwargs : t .Any ,
23562375 ) -> None :
23572376 assert isinstance (model .kind , (SCDType2ByTimeKind , SCDType2ByColumnKind ))
@@ -2381,11 +2400,13 @@ def create(
23812400 model ,
23822401 is_table_deployable ,
23832402 render_kwargs ,
2403+ skip_grants ,
23842404 ** kwargs ,
23852405 )
23862406
2387- # Apply grants after SCD Type 2 table creation
2388- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2407+ if not skip_grants :
2408+ # Apply grants after SCD Type 2 table creation
2409+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
23892410
23902411 def insert (
23912412 self ,
@@ -2529,14 +2550,17 @@ def create(
25292550 model : Model ,
25302551 is_table_deployable : bool ,
25312552 render_kwargs : t .Dict [str , t .Any ],
2553+ skip_grants : bool ,
25322554 ** kwargs : t .Any ,
25332555 ) -> None :
25342556 if self .adapter .table_exists (table_name ):
25352557 # Make sure we don't recreate the view to prevent deletion of downstream views in engines with no late
25362558 # binding support (because of DROP CASCADE).
25372559 logger .info ("View '%s' already exists" , table_name )
2538- # Always apply grants when present, even if view exists, to handle grants updates
2539- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2560+
2561+ if not skip_grants :
2562+ # Always apply grants when present, even if view exists, to handle grants updates
2563+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
25402564 return
25412565
25422566 logger .info ("Creating view '%s'" , table_name )
@@ -2560,8 +2584,9 @@ def create(
25602584 column_descriptions = model .column_descriptions if is_table_deployable else None ,
25612585 )
25622586
2563- # Apply grants after view creation
2564- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2587+ if not skip_grants :
2588+ # Apply grants after view creation
2589+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
25652590
25662591 def migrate (
25672592 self ,
@@ -2877,6 +2902,7 @@ def create(
28772902 model : Model ,
28782903 is_table_deployable : bool ,
28792904 render_kwargs : t .Dict [str , t .Any ],
2905+ skip_grants : bool ,
28802906 ** kwargs : t .Any ,
28812907 ) -> None :
28822908 is_snapshot_deployable : bool = kwargs ["is_snapshot_deployable" ]
@@ -2897,24 +2923,21 @@ def create(
28972923 )
28982924
28992925 # Apply grants after managed table creation
2900- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2926+ if not skip_grants :
2927+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
29012928
29022929 elif not is_table_deployable :
29032930 # Only create the dev preview table as a normal table.
29042931 # For the main table, if the snapshot is cant be deployed to prod (eg upstream is forward-only) do nothing.
29052932 # Any downstream models that reference it will be updated to point to the dev preview table.
29062933 # If the user eventually tries to deploy it, the logic in insert() will see it doesnt exist and create it
2907-
2908- # Create preview table but don't apply grants here since the table is not deployable
2909- # Grants will be applied later when the table becomes deployable
2910- kwargs_no_grants = {** kwargs }
2911- kwargs_no_grants ["skip_grants" ] = True
29122934 super ().create (
29132935 table_name = table_name ,
29142936 model = model ,
29152937 is_table_deployable = is_table_deployable ,
29162938 render_kwargs = render_kwargs ,
2917- ** kwargs_no_grants ,
2939+ skip_grants = skip_grants ,
2940+ ** kwargs ,
29182941 )
29192942
29202943 def insert (
@@ -2941,6 +2964,7 @@ def insert(
29412964 column_descriptions = model .column_descriptions ,
29422965 table_format = model .table_format ,
29432966 )
2967+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
29442968 elif not is_snapshot_deployable :
29452969 # Snapshot isnt deployable; update the preview table instead
29462970 # If the snapshot was deployable, then data would have already been loaded in create() because a managed table would have been created
@@ -2990,7 +3014,7 @@ def migrate(
29903014 )
29913015
29923016 # Apply grants after verifying no schema changes
2993- # This ensures metadata-only changes ( grants) are applied
3017+ # This ensures metadata-only grants changes are applied
29943018 self ._apply_grants (snapshot .model , target_table_name , GrantsTargetLayer .PHYSICAL )
29953019
29963020 def delete (self , name : str , ** kwargs : t .Any ) -> None :
0 commit comments