@@ -167,6 +167,7 @@ def test_json(snapshot: Snapshot):
167167 "enabled" : True ,
168168 "extract_dependencies_from_query" : True ,
169169 "virtual_environment_mode" : "full" ,
170+ "grants_target_layer" : "all" ,
170171 },
171172 "name" : '"name"' ,
172173 "parents" : [{"name" : '"parent"."tbl"' , "identifier" : snapshot .parents [0 ].identifier }],
@@ -180,6 +181,36 @@ def test_json(snapshot: Snapshot):
180181 }
181182
182183
184+ def test_json_with_grants (make_snapshot : t .Callable ):
185+ from sqlmesh .core .model .meta import GrantsTargetLayer
186+
187+ model = SqlModel (
188+ name = "name" ,
189+ kind = dict (time_column = "ds" , batch_size = 30 , name = ModelKindName .INCREMENTAL_BY_TIME_RANGE ),
190+ owner = "owner" ,
191+ dialect = "spark" ,
192+ cron = "1 0 * * *" ,
193+ start = "2020-01-01" ,
194+ query = parse_one ("SELECT @EACH([1, 2], x -> x), ds FROM parent.tbl" ),
195+ grants = {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]},
196+ grants_target_layer = GrantsTargetLayer .VIRTUAL ,
197+ )
198+ snapshot = make_snapshot (model )
199+
200+ json_str = snapshot .json ()
201+ json_data = json .loads (json_str )
202+ assert (
203+ json_data ["node" ]["grants" ]
204+ == "('SELECT' = ARRAY('role1', 'role2'), 'INSERT' = ARRAY('role3'))"
205+ )
206+ assert json_data ["node" ]["grants_target_layer" ] == "virtual"
207+
208+ reparsed_snapshot = Snapshot .model_validate_json (json_str )
209+ assert isinstance (reparsed_snapshot .node , SqlModel )
210+ assert reparsed_snapshot .node .grants == {"SELECT" : ["role1" , "role2" ], "INSERT" : ["role3" ]}
211+ assert reparsed_snapshot .node .grants_target_layer == GrantsTargetLayer .VIRTUAL
212+
213+
183214def test_json_custom_materialization (make_snapshot : t .Callable ):
184215 model = SqlModel (
185216 name = "name" ,
@@ -916,7 +947,7 @@ def test_fingerprint(model: Model, parent_model: Model):
916947
917948 original_fingerprint = SnapshotFingerprint (
918949 data_hash = "2406542604" ,
919- metadata_hash = "3341445192 " ,
950+ metadata_hash = "185287368 " ,
920951 )
921952
922953 assert fingerprint == original_fingerprint
@@ -977,7 +1008,7 @@ def test_fingerprint_seed_model():
9771008
9781009 expected_fingerprint = SnapshotFingerprint (
9791010 data_hash = "1586624913" ,
980- metadata_hash = "2315134974 " ,
1011+ metadata_hash = "1817881990 " ,
9811012 )
9821013
9831014 model = load_sql_based_model (expressions , path = Path ("./examples/sushi/models/test_model.sql" ))
@@ -1016,7 +1047,7 @@ def test_fingerprint_jinja_macros(model: Model):
10161047 )
10171048 original_fingerprint = SnapshotFingerprint (
10181049 data_hash = "93332825" ,
1019- metadata_hash = "3341445192 " ,
1050+ metadata_hash = "185287368 " ,
10201051 )
10211052
10221053 fingerprint = fingerprint_from_node (model , nodes = {})
@@ -1091,6 +1122,40 @@ def test_fingerprint_virtual_properties(model: Model, parent_model: Model):
10911122 assert updated_fingerprint .data_hash == fingerprint .data_hash
10921123
10931124
1125+ def test_fingerprint_grants (model : Model , parent_model : Model ):
1126+ from sqlmesh .core .model .meta import GrantsTargetLayer
1127+
1128+ original_model = deepcopy (model )
1129+ fingerprint = fingerprint_from_node (model , nodes = {})
1130+
1131+ updated_model = SqlModel (
1132+ ** original_model .dict (),
1133+ grants = {"SELECT" : ["role1" , "role2" ]},
1134+ )
1135+ updated_fingerprint = fingerprint_from_node (updated_model , nodes = {})
1136+
1137+ assert updated_fingerprint != fingerprint
1138+ assert updated_fingerprint .metadata_hash != fingerprint .metadata_hash
1139+ assert updated_fingerprint .data_hash == fingerprint .data_hash
1140+
1141+ different_grants_model = SqlModel (
1142+ ** original_model .dict (),
1143+ grants = {"SELECT" : ["role3" ], "INSERT" : ["role4" ]},
1144+ )
1145+ different_grants_fingerprint = fingerprint_from_node (different_grants_model , nodes = {})
1146+
1147+ assert different_grants_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1148+ assert different_grants_fingerprint .metadata_hash != fingerprint .metadata_hash
1149+
1150+ target_layer_model = SqlModel (
1151+ ** {** original_model .dict (), "grants_target_layer" : GrantsTargetLayer .PHYSICAL },
1152+ grants = {"SELECT" : ["role1" , "role2" ]},
1153+ )
1154+ target_layer_fingerprint = fingerprint_from_node (target_layer_model , nodes = {})
1155+
1156+ assert target_layer_fingerprint .metadata_hash != updated_fingerprint .metadata_hash
1157+
1158+
10941159def test_tableinfo_equality ():
10951160 snapshot_a = SnapshotTableInfo (
10961161 name = "test_schema.a" ,
0 commit comments