@@ -165,6 +165,7 @@ def test_json(snapshot: Snapshot):
165165 "enabled" : True ,
166166 "extract_dependencies_from_query" : True ,
167167 "virtual_environment_mode" : "full" ,
168+ "grants_target_layer" : "all" ,
168169 },
169170 "name" : '"name"' ,
170171 "parents" : [{"name" : '"parent"."tbl"' , "identifier" : snapshot .parents [0 ].identifier }],
@@ -178,6 +179,33 @@ def test_json(snapshot: Snapshot):
178179 }
179180
180181
182+ def test_json_with_grants (make_snapshot : t .Callable ):
183+ from sqlmesh .core .model .meta import GrantsTargetLayer
184+
185+ model = SqlModel (
186+ name = "name" ,
187+ kind = dict (time_column = "ds" , batch_size = 30 , name = ModelKindName .INCREMENTAL_BY_TIME_RANGE ),
188+ owner = "owner" ,
189+ dialect = "spark" ,
190+ cron = "1 0 * * *" ,
191+ start = "2020-01-01" ,
192+ query = parse_one ("SELECT @EACH([1, 2], x -> x), ds FROM parent.tbl" ),
193+ grants = {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]},
194+ grants_target_layer = GrantsTargetLayer .VIRTUAL ,
195+ )
196+ snapshot = make_snapshot (model )
197+
198+ json_str = snapshot .json ()
199+ json_data = json .loads (json_str )
200+ assert json_data ["node" ]["grants" ] == {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]}
201+ assert json_data ["node" ]["grants_target_layer" ] == "virtual"
202+
203+ reparsed_snapshot = Snapshot .model_validate_json (json_str )
204+ assert isinstance (reparsed_snapshot .node , SqlModel )
205+ assert reparsed_snapshot .node .grants == {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]}
206+ assert reparsed_snapshot .node .grants_target_layer == GrantsTargetLayer .VIRTUAL
207+
208+
181209def test_json_custom_materialization (make_snapshot : t .Callable ):
182210 model = SqlModel (
183211 name = "name" ,
@@ -914,7 +942,7 @@ def test_fingerprint(model: Model, parent_model: Model):
914942
915943 original_fingerprint = SnapshotFingerprint (
916944 data_hash = "3301649319" ,
917- metadata_hash = "3575333731 " ,
945+ metadata_hash = "4020678062 " ,
918946 )
919947
920948 assert fingerprint == original_fingerprint
@@ -975,7 +1003,7 @@ def test_fingerprint_seed_model():
9751003
9761004 expected_fingerprint = SnapshotFingerprint (
9771005 data_hash = "1586624913" ,
978- metadata_hash = "2315134974 " ,
1006+ metadata_hash = "1817881990 " ,
9791007 )
9801008
9811009 model = load_sql_based_model (expressions , path = Path ("./examples/sushi/models/test_model.sql" ))
@@ -1014,7 +1042,7 @@ def test_fingerprint_jinja_macros(model: Model):
10141042 )
10151043 original_fingerprint = SnapshotFingerprint (
10161044 data_hash = "2908339239" ,
1017- metadata_hash = "3575333731 " ,
1045+ metadata_hash = "4020678062 " ,
10181046 )
10191047
10201048 fingerprint = fingerprint_from_node (model , nodes = {})
@@ -1089,6 +1117,41 @@ def test_fingerprint_virtual_properties(model: Model, parent_model: Model):
10891117 assert updated_fingerprint .data_hash == fingerprint .data_hash
10901118
10911119
1120+ def test_fingerprint_grants (model : Model , parent_model : Model ):
1121+ from sqlmesh .core .model .meta import GrantsTargetLayer
1122+
1123+ original_model = deepcopy (model )
1124+ fingerprint = fingerprint_from_node (model , nodes = {})
1125+
1126+ updated_model = SqlModel (
1127+ ** original_model .dict (),
1128+ grants = {"SELECT" : ["role1" , "role2" ]},
1129+ )
1130+ updated_fingerprint = fingerprint_from_node (updated_model , nodes = {})
1131+
1132+ assert updated_fingerprint != fingerprint
1133+ assert updated_fingerprint .metadata_hash != fingerprint .metadata_hash
1134+ assert updated_fingerprint .data_hash == fingerprint .data_hash
1135+
1136+ different_grants_model = SqlModel (
1137+ ** original_model .dict (),
1138+ grants = {"SELECT" : ["role3" ], "INSERT" : ["role4" ]},
1139+ )
1140+ different_grants_fingerprint = fingerprint_from_node (different_grants_model , nodes = {})
1141+
1142+ assert different_grants_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1143+ assert different_grants_fingerprint .metadata_hash != fingerprint .metadata_hash
1144+
1145+ target_layer_model = SqlModel (
1146+ ** original_model .dict (),
1147+ grants = {"SELECT" : ["role1" , "role2" ]},
1148+ grants_target_layer = GrantsTargetLayer .PHYSICAL ,
1149+ )
1150+ target_layer_fingerprint = fingerprint_from_node (target_layer_model , nodes = {})
1151+
1152+ assert target_layer_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1153+
1154+
10921155def test_tableinfo_equality ():
10931156 snapshot_a = SnapshotTableInfo (
10941157 name = "test_schema.a" ,
0 commit comments