4545from dbt .adapters .bigquery import BigQueryColumn , BigQueryConnectionManager
4646from dbt .adapters .bigquery .column import get_nested_column_data_types
4747from dbt .adapters .bigquery .connections import BigQueryAdapterResponse
48- from dbt .adapters .bigquery .dataset import add_access_entry_to_dataset , is_access_entry_in_dataset
48+ from dbt .adapters .bigquery .dataset import add_access_entry_to_dataset , is_access_entry_in_dataset , delete_access_entry_to_dataset
4949from dbt .adapters .bigquery .python_submissions import (
5050 ClusterDataprocHelper ,
5151 ServerlessDataProcHelper ,
@@ -817,10 +817,12 @@ def describe_relation(
817817 return parser .from_bq_table (bq_table )
818818 return None
819819
820+
821+
820822 @available .parse_none
821- def grant_access_to (self , entity , entity_type , role , grant_target_dict ):
823+ def grant_access_to (self , entity , entity_type , role , grant_target_dict , full_refresh = False ):
822824 """
823- Given an entity, grants it access to a dataset.
825+ Given an entity, grants access to a dataset.
824826 """
825827 conn : BigQueryConnectionManager = self .connections .get_thread_connection ()
826828 client = conn .handle
@@ -832,14 +834,54 @@ def grant_access_to(self, entity, entity_type, role, grant_target_dict):
832834 dataset_ref = self .connections .dataset_ref (grant_target .project , grant_target .dataset )
833835 dataset = client .get_dataset (dataset_ref )
834836 access_entry = AccessEntry (role , entity_type , entity )
835- # only perform update if access entry not in dataset
837+ # only perform update if access entry in dataset but if full_refresh remove it first
836838 if is_access_entry_in_dataset (dataset , access_entry ):
837- logger .warning (f"Access entry { access_entry } " f"already exists in dataset" )
838- else :
839- dataset = add_access_entry_to_dataset (dataset , access_entry )
840- client .update_dataset (dataset , ["access_entries" ])
839+ if not full_refresh :
840+ logger .warning (f"Access entry { access_entry } " f"already exists in dataset" )
841+ return
842+ else :
843+ dataset = delete_access_entry_to_dataset (dataset ,access_entry )
844+ dataset = client .update_dataset (
845+ dataset ,
846+ ["access_entries" ],
847+ ) # Make an API request.
848+ full_dataset_id = f"{ dataset .project } .{ dataset .dataset_id } "
849+ print (f"Revoked dataset access for '{ access_entry .entity_id } ' to ' dataset '{ full_dataset_id } .'" )
850+ dataset = add_access_entry_to_dataset (dataset , access_entry )
851+ dataset = client .update_dataset (dataset , ["access_entries" ])
852+ full_dataset_id = f"{ dataset .project } .{ dataset .dataset_id } "
853+ print (f"allowed dataset access for '{ access_entry .entity_id } ' to ' dataset '{ full_dataset_id } .'" )
841854
842855 @available .parse_none
856+ def remove_grant_access_to (self , entity , entity_type , role , grant_target_dict ):
857+ """
858+ Given an entity, grants access to a dataset.
859+ """
860+ conn : BigQueryConnectionManager = self .connections .get_thread_connection ()
861+ client = conn .handle
862+ GrantTarget .validate (grant_target_dict )
863+ grant_target = GrantTarget .from_dict (grant_target_dict )
864+ if entity_type == "view" :
865+ entity = self .get_table_ref_from_relation (entity ).to_api_repr ()
866+ with _dataset_lock :
867+ dataset_ref = self .connections .dataset_ref (grant_target .project , grant_target .dataset )
868+ dataset = client .get_dataset (dataset_ref )
869+ access_entry = AccessEntry (role , entity_type , entity )
870+ # only perform removing if access entry in dataset
871+ if is_access_entry_in_dataset (dataset , access_entry ):
872+ dataset = delete_access_entry_to_dataset (dataset ,access_entry )
873+ dataset = client .update_dataset (
874+ dataset ,
875+ ["access_entries" ],
876+ ) # Make an API request.
877+
878+ full_dataset_id = f"{ dataset .project } .{ dataset .dataset_id } "
879+ print (f"Revoked dataset access for '{ access_entry .entity_id } ' to ' dataset '{ full_dataset_id } .'" )
880+ else :
881+ logger .warning (f"Access entry { access_entry } not in the dataset { full_dataset_id } no need to remove it" )
882+ @available .parse_none
883+
884+
843885 def get_dataset_location (self , relation ):
844886 conn = self .connections .get_thread_connection ()
845887 client = conn .handle
0 commit comments