@@ -168,6 +168,7 @@ def test_json(snapshot: Snapshot):
168168 "enabled" : True ,
169169 "extract_dependencies_from_query" : True ,
170170 "virtual_environment_mode" : "full" ,
171+ "grants_target_layer" : "all" ,
171172 },
172173 "name" : '"name"' ,
173174 "parents" : [{"name" : '"parent"."tbl"' , "identifier" : snapshot .parents [0 ].identifier }],
@@ -181,6 +182,36 @@ def test_json(snapshot: Snapshot):
181182 }
182183
183184
185+ def test_json_with_grants (make_snapshot : t .Callable ):
186+ from sqlmesh .core .model .meta import GrantsTargetLayer
187+
188+ model = SqlModel (
189+ name = "name" ,
190+ kind = dict (time_column = "ds" , batch_size = 30 , name = ModelKindName .INCREMENTAL_BY_TIME_RANGE ),
191+ owner = "owner" ,
192+ dialect = "spark" ,
193+ cron = "1 0 * * *" ,
194+ start = "2020-01-01" ,
195+ query = parse_one ("SELECT @EACH([1, 2], x -> x), ds FROM parent.tbl" ),
196+ grants = {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]},
197+ grants_target_layer = GrantsTargetLayer .VIRTUAL ,
198+ )
199+ snapshot = make_snapshot (model )
200+
201+ json_str = snapshot .json ()
202+ json_data = json .loads (json_str )
203+ assert (
204+ json_data ["node" ]["grants" ]
205+ == "('SELECT' = ARRAY('role1', 'role2'), 'INSERT' = ARRAY('role3'))"
206+ )
207+ assert json_data ["node" ]["grants_target_layer" ] == "virtual"
208+
209+ reparsed_snapshot = Snapshot .model_validate_json (json_str )
210+ assert isinstance (reparsed_snapshot .node , SqlModel )
211+ assert reparsed_snapshot .node .grants == {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]}
212+ assert reparsed_snapshot .node .grants_target_layer == GrantsTargetLayer .VIRTUAL
213+
214+
184215def test_json_custom_materialization (make_snapshot : t .Callable ):
185216 model = SqlModel (
186217 name = "name" ,
@@ -954,7 +985,7 @@ def test_fingerprint(model: Model, parent_model: Model):
954985
955986 original_fingerprint = SnapshotFingerprint (
956987 data_hash = "2406542604" ,
957- metadata_hash = "3341445192 " ,
988+ metadata_hash = "185287368 " ,
958989 )
959990
960991 assert fingerprint == original_fingerprint
@@ -1015,7 +1046,7 @@ def test_fingerprint_seed_model():
10151046
10161047 expected_fingerprint = SnapshotFingerprint (
10171048 data_hash = "1586624913" ,
1018- metadata_hash = "2315134974 " ,
1049+ metadata_hash = "1817881990 " ,
10191050 )
10201051
10211052 model = load_sql_based_model (expressions , path = Path ("./examples/sushi/models/test_model.sql" ))
@@ -1054,7 +1085,7 @@ def test_fingerprint_jinja_macros(model: Model):
10541085 )
10551086 original_fingerprint = SnapshotFingerprint (
10561087 data_hash = "93332825" ,
1057- metadata_hash = "3341445192 " ,
1088+ metadata_hash = "185287368 " ,
10581089 )
10591090
10601091 fingerprint = fingerprint_from_node (model , nodes = {})
@@ -1131,6 +1162,40 @@ def test_fingerprint_virtual_properties(model: Model, parent_model: Model):
11311162 assert updated_fingerprint .data_hash == fingerprint .data_hash
11321163
11331164
1165+ def test_fingerprint_grants (model : Model , parent_model : Model ):
1166+ from sqlmesh .core .model .meta import GrantsTargetLayer
1167+
1168+ original_model = deepcopy (model )
1169+ fingerprint = fingerprint_from_node (model , nodes = {})
1170+
1171+ updated_model = SqlModel (
1172+ ** original_model .dict (),
1173+ grants = {"SELECT" : ["role1" , "role2" ]},
1174+ )
1175+ updated_fingerprint = fingerprint_from_node (updated_model , nodes = {})
1176+
1177+ assert updated_fingerprint != fingerprint
1178+ assert updated_fingerprint .metadata_hash != fingerprint .metadata_hash
1179+ assert updated_fingerprint .data_hash == fingerprint .data_hash
1180+
1181+ different_grants_model = SqlModel (
1182+ ** original_model .dict (),
1183+ grants = {"SELECT" : ["role3" ], "INSERT" : ["role4" ]},
1184+ )
1185+ different_grants_fingerprint = fingerprint_from_node (different_grants_model , nodes = {})
1186+
1187+ assert different_grants_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1188+ assert different_grants_fingerprint .metadata_hash != fingerprint .metadata_hash
1189+
1190+ target_layer_model = SqlModel (
1191+ ** {** original_model .dict (), "grants_target_layer" : GrantsTargetLayer .PHYSICAL },
1192+ grants = {"SELECT" : ["role1" , "role2" ]},
1193+ )
1194+ target_layer_fingerprint = fingerprint_from_node (target_layer_model , nodes = {})
1195+
1196+ assert target_layer_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1197+
1198+
11341199def test_tableinfo_equality ():
11351200 snapshot_a = SnapshotTableInfo (
11361201 name = "test_schema.a" ,
0 commit comments