@@ -1408,12 +1408,12 @@ def _execute_create(
14081408 table_name = table_name ,
14091409 model = snapshot .model ,
14101410 is_table_deployable = is_table_deployable ,
1411+ skip_grants = skip_grants ,
14111412 render_kwargs = create_render_kwargs ,
14121413 is_snapshot_deployable = is_snapshot_deployable ,
14131414 is_snapshot_representative = is_snapshot_representative ,
14141415 dry_run = dry_run ,
14151416 physical_properties = rendered_physical_properties ,
1416- skip_grants = skip_grants ,
14171417 )
14181418 if run_pre_post_statements :
14191419 adapter .execute (snapshot .model .render_post_statements (** create_render_kwargs ))
@@ -1577,6 +1577,7 @@ def create(
15771577 model : Model ,
15781578 is_table_deployable : bool ,
15791579 render_kwargs : t .Dict [str , t .Any ],
1580+ skip_grants : bool ,
15801581 ** kwargs : t .Any ,
15811582 ) -> None :
15821583 """Creates the target table or view.
@@ -1720,6 +1721,7 @@ def create(
17201721 model : Model ,
17211722 is_table_deployable : bool ,
17221723 render_kwargs : t .Dict [str , t .Any ],
1724+ skip_grants : bool ,
17231725 ** kwargs : t .Any ,
17241726 ) -> None :
17251727 pass
@@ -1795,10 +1797,10 @@ def promote(
17951797 view_properties = model .render_virtual_properties (** render_kwargs ),
17961798 )
17971799
1798- # Apply grants to the physical layer table
1800+ # Apply grants to the physical layer (referenced table / view) after promotion
17991801 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18001802
1801- # Apply grants to the virtual layer view
1803+ # Apply grants to the virtual layer ( view) after promotion
18021804 self ._apply_grants (model , view_name , GrantsTargetLayer .VIRTUAL )
18031805
18041806 def demote (self , view_name : str , ** kwargs : t .Any ) -> None :
@@ -1813,6 +1815,7 @@ def create(
18131815 model : Model ,
18141816 is_table_deployable : bool ,
18151817 render_kwargs : t .Dict [str , t .Any ],
1818+ skip_grants : bool ,
18161819 ** kwargs : t .Any ,
18171820 ) -> None :
18181821 ctas_query = model .ctas_query (** render_kwargs )
@@ -1858,7 +1861,7 @@ def create(
18581861 )
18591862
18601863 # Apply grants after table creation (unless explicitly skipped by caller)
1861- if not kwargs . get ( " skip_grants" , False ) :
1864+ if not skip_grants :
18621865 self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
18631866
18641867 def migrate (
@@ -1900,6 +1903,7 @@ def _replace_query_for_model(
19001903 name : str ,
19011904 query_or_df : QueryOrDF ,
19021905 render_kwargs : t .Dict [str , t .Any ],
1906+ skip_grants : bool = False ,
19031907 ** kwargs : t .Any ,
19041908 ) -> None :
19051909 """Replaces the table for the given model.
@@ -1937,7 +1941,7 @@ def _replace_query_for_model(
19371941 )
19381942
19391943 # Apply grants after table replacement (unless explicitly skipped by caller)
1940- if not kwargs . get ( " skip_grants" , False ) :
1944+ if not skip_grants :
19411945 self ._apply_grants (model , name , GrantsTargetLayer .PHYSICAL )
19421946
19431947 def _get_target_and_source_columns (
@@ -2187,6 +2191,7 @@ def create(
21872191 model : Model ,
21882192 is_table_deployable : bool ,
21892193 render_kwargs : t .Dict [str , t .Any ],
2194+ skip_grants : bool ,
21902195 ** kwargs : t .Any ,
21912196 ) -> None :
21922197 model = t .cast (SeedModel , model )
@@ -2200,29 +2205,38 @@ def create(
22002205 )
22012206 return
22022207
2203- # Skip grants in parent create call since we'll apply them after data insertion
2204- kwargs_no_grants = {** kwargs }
2205- kwargs_no_grants ["skip_grants" ] = True
2206-
2207- super ().create (table_name , model , is_table_deployable , render_kwargs , ** kwargs_no_grants )
2208+ super ().create (
2209+ table_name ,
2210+ model ,
2211+ is_table_deployable ,
2212+ render_kwargs ,
2213+ skip_grants = True , # Skip grants; they're applied after data insertion
2214+ ** kwargs ,
2215+ )
22082216 # For seeds we insert data at the time of table creation.
22092217 try :
22102218 for index , df in enumerate (model .render_seed ()):
22112219 if index == 0 :
22122220 self ._replace_query_for_model (
2213- model , table_name , df , render_kwargs , ** kwargs_no_grants
2221+ model ,
2222+ table_name ,
2223+ df ,
2224+ render_kwargs ,
2225+ skip_grants = True , # Skip grants; they're applied after data insertion
2226+ ** kwargs ,
22142227 )
22152228 else :
22162229 self .adapter .insert_append (
22172230 table_name , df , target_columns_to_types = model .columns_to_types
22182231 )
2232+
2233+ if not skip_grants :
2234+ # Apply grants after seed table creation and data insertion
2235+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
22192236 except Exception :
22202237 self .adapter .drop_table (table_name )
22212238 raise
22222239
2223- # Apply grants after seed table creation or data insertion
2224- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2225-
22262240 def insert (
22272241 self ,
22282242 table_name : str ,
@@ -2254,6 +2268,7 @@ def create(
22542268 model : Model ,
22552269 is_table_deployable : bool ,
22562270 render_kwargs : t .Dict [str , t .Any ],
2271+ skip_grants : bool ,
22572272 ** kwargs : t .Any ,
22582273 ) -> None :
22592274 assert isinstance (model .kind , (SCDType2ByTimeKind , SCDType2ByColumnKind ))
@@ -2283,11 +2298,13 @@ def create(
22832298 model ,
22842299 is_table_deployable ,
22852300 render_kwargs ,
2301+ skip_grants ,
22862302 ** kwargs ,
22872303 )
22882304
2289- # Apply grants after SCD Type 2 table creation
2290- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2305+ if not skip_grants :
2306+ # Apply grants after SCD Type 2 table creation
2307+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
22912308
22922309 def insert (
22932310 self ,
@@ -2431,14 +2448,17 @@ def create(
24312448 model : Model ,
24322449 is_table_deployable : bool ,
24332450 render_kwargs : t .Dict [str , t .Any ],
2451+ skip_grants : bool ,
24342452 ** kwargs : t .Any ,
24352453 ) -> None :
24362454 if self .adapter .table_exists (table_name ):
24372455 # Make sure we don't recreate the view to prevent deletion of downstream views in engines with no late
24382456 # binding support (because of DROP CASCADE).
24392457 logger .info ("View '%s' already exists" , table_name )
2440- # Always apply grants when present, even if view exists, to handle grants updates
2441- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2458+
2459+ if not skip_grants :
2460+ # Always apply grants when present, even if view exists, to handle grants updates
2461+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24422462 return
24432463
24442464 logger .info ("Creating view '%s'" , table_name )
@@ -2462,8 +2482,9 @@ def create(
24622482 column_descriptions = model .column_descriptions if is_table_deployable else None ,
24632483 )
24642484
2465- # Apply grants after view creation
2466- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2485+ if not skip_grants :
2486+ # Apply grants after view creation
2487+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
24672488
24682489 def migrate (
24692490 self ,
@@ -2640,6 +2661,7 @@ def create(
26402661 model : Model ,
26412662 is_table_deployable : bool ,
26422663 render_kwargs : t .Dict [str , t .Any ],
2664+ skip_grants : bool ,
26432665 ** kwargs : t .Any ,
26442666 ) -> None :
26452667 is_snapshot_deployable : bool = kwargs ["is_snapshot_deployable" ]
@@ -2660,24 +2682,21 @@ def create(
26602682 )
26612683
26622684 # Apply grants after managed table creation
2663- self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
2685+ if not skip_grants :
2686+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
26642687
26652688 elif not is_table_deployable :
26662689 # Only create the dev preview table as a normal table.
26672690 # For the main table, if the snapshot is cant be deployed to prod (eg upstream is forward-only) do nothing.
26682691 # Any downstream models that reference it will be updated to point to the dev preview table.
26692692 # If the user eventually tries to deploy it, the logic in insert() will see it doesnt exist and create it
2670-
2671- # Create preview table but don't apply grants here since the table is not deployable
2672- # Grants will be applied later when the table becomes deployable
2673- kwargs_no_grants = {** kwargs }
2674- kwargs_no_grants ["skip_grants" ] = True
26752693 super ().create (
26762694 table_name = table_name ,
26772695 model = model ,
26782696 is_table_deployable = is_table_deployable ,
26792697 render_kwargs = render_kwargs ,
2680- ** kwargs_no_grants ,
2698+ skip_grants = skip_grants ,
2699+ ** kwargs ,
26812700 )
26822701
26832702 def insert (
@@ -2704,6 +2723,7 @@ def insert(
27042723 column_descriptions = model .column_descriptions ,
27052724 table_format = model .table_format ,
27062725 )
2726+ self ._apply_grants (model , table_name , GrantsTargetLayer .PHYSICAL )
27072727 elif not is_snapshot_deployable :
27082728 # Snapshot isnt deployable; update the preview table instead
27092729 # If the snapshot was deployable, then data would have already been loaded in create() because a managed table would have been created
@@ -2753,7 +2773,7 @@ def migrate(
27532773 )
27542774
27552775 # Apply grants after verifying no schema changes
2756- # This ensures metadata-only changes ( grants) are applied
2776+ # This ensures metadata-only grants changes are applied
27572777 self ._apply_grants (snapshot .model , target_table_name , GrantsTargetLayer .PHYSICAL )
27582778
27592779 def delete (self , name : str , ** kwargs : t .Any ) -> None :
0 commit comments