snowflake-ml-python 1.8.2__py3-none-any.whl → 1.8.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. snowflake/cortex/_classify_text.py +3 -3
  2. snowflake/cortex/_complete.py +23 -24
  3. snowflake/cortex/_embed_text_1024.py +4 -4
  4. snowflake/cortex/_embed_text_768.py +4 -4
  5. snowflake/cortex/_finetune.py +8 -8
  6. snowflake/cortex/_util.py +8 -12
  7. snowflake/ml/_internal/env.py +4 -3
  8. snowflake/ml/_internal/env_utils.py +63 -34
  9. snowflake/ml/_internal/file_utils.py +10 -21
  10. snowflake/ml/_internal/human_readable_id/hrid_generator_base.py +5 -7
  11. snowflake/ml/_internal/init_utils.py +2 -3
  12. snowflake/ml/_internal/lineage/lineage_utils.py +6 -6
  13. snowflake/ml/_internal/platform_capabilities.py +6 -6
  14. snowflake/ml/_internal/telemetry.py +39 -52
  15. snowflake/ml/_internal/type_utils.py +3 -3
  16. snowflake/ml/_internal/utils/db_utils.py +2 -2
  17. snowflake/ml/_internal/utils/identifier.py +8 -8
  18. snowflake/ml/_internal/utils/import_utils.py +2 -2
  19. snowflake/ml/_internal/utils/parallelize.py +7 -7
  20. snowflake/ml/_internal/utils/pkg_version_utils.py +11 -11
  21. snowflake/ml/_internal/utils/query_result_checker.py +4 -4
  22. snowflake/ml/_internal/utils/snowflake_env.py +28 -6
  23. snowflake/ml/_internal/utils/snowpark_dataframe_utils.py +2 -2
  24. snowflake/ml/_internal/utils/sql_identifier.py +3 -3
  25. snowflake/ml/_internal/utils/table_manager.py +9 -9
  26. snowflake/ml/data/_internal/arrow_ingestor.py +7 -7
  27. snowflake/ml/data/data_connector.py +15 -36
  28. snowflake/ml/data/data_ingestor.py +4 -15
  29. snowflake/ml/data/data_source.py +2 -2
  30. snowflake/ml/data/ingestor_utils.py +3 -3
  31. snowflake/ml/data/torch_utils.py +5 -5
  32. snowflake/ml/dataset/dataset.py +11 -11
  33. snowflake/ml/dataset/dataset_metadata.py +8 -8
  34. snowflake/ml/dataset/dataset_reader.py +7 -7
  35. snowflake/ml/feature_store/__init__.py +1 -1
  36. snowflake/ml/feature_store/access_manager.py +7 -7
  37. snowflake/ml/feature_store/entity.py +6 -6
  38. snowflake/ml/feature_store/examples/airline_features/entities.py +1 -3
  39. snowflake/ml/feature_store/examples/airline_features/features/plane_features.py +1 -3
  40. snowflake/ml/feature_store/examples/airline_features/features/weather_features.py +1 -3
  41. snowflake/ml/feature_store/examples/citibike_trip_features/entities.py +1 -3
  42. snowflake/ml/feature_store/examples/citibike_trip_features/features/station_feature.py +1 -3
  43. snowflake/ml/feature_store/examples/citibike_trip_features/features/trip_feature.py +1 -3
  44. snowflake/ml/feature_store/examples/example_helper.py +16 -16
  45. snowflake/ml/feature_store/examples/new_york_taxi_features/entities.py +1 -3
  46. snowflake/ml/feature_store/examples/new_york_taxi_features/features/location_features.py +1 -3
  47. snowflake/ml/feature_store/examples/new_york_taxi_features/features/trip_features.py +1 -3
  48. snowflake/ml/feature_store/examples/wine_quality_features/entities.py +1 -3
  49. snowflake/ml/feature_store/examples/wine_quality_features/features/managed_wine_features.py +1 -3
  50. snowflake/ml/feature_store/examples/wine_quality_features/features/static_wine_features.py +1 -3
  51. snowflake/ml/feature_store/feature_store.py +52 -64
  52. snowflake/ml/feature_store/feature_view.py +24 -24
  53. snowflake/ml/fileset/embedded_stage_fs.py +5 -5
  54. snowflake/ml/fileset/fileset.py +5 -5
  55. snowflake/ml/fileset/sfcfs.py +13 -13
  56. snowflake/ml/fileset/stage_fs.py +15 -15
  57. snowflake/ml/jobs/_utils/interop_utils.py +10 -10
  58. snowflake/ml/jobs/_utils/payload_utils.py +6 -16
  59. snowflake/ml/jobs/_utils/scripts/mljob_launcher.py +7 -4
  60. snowflake/ml/jobs/_utils/scripts/signal_workers.py +8 -8
  61. snowflake/ml/jobs/_utils/spec_utils.py +17 -28
  62. snowflake/ml/jobs/_utils/types.py +2 -2
  63. snowflake/ml/jobs/decorators.py +4 -5
  64. snowflake/ml/jobs/job.py +24 -14
  65. snowflake/ml/jobs/manager.py +37 -41
  66. snowflake/ml/lineage/lineage_node.py +5 -5
  67. snowflake/ml/model/_client/model/model_impl.py +3 -3
  68. snowflake/ml/model/_client/model/model_version_impl.py +103 -35
  69. snowflake/ml/model/_client/ops/metadata_ops.py +7 -7
  70. snowflake/ml/model/_client/ops/model_ops.py +41 -41
  71. snowflake/ml/model/_client/ops/service_ops.py +199 -26
  72. snowflake/ml/model/_client/service/model_deployment_spec.py +171 -47
  73. snowflake/ml/model/_client/service/model_deployment_spec_schema.py +44 -24
  74. snowflake/ml/model/_client/sql/model.py +8 -8
  75. snowflake/ml/model/_client/sql/model_version.py +26 -26
  76. snowflake/ml/model/_client/sql/service.py +13 -13
  77. snowflake/ml/model/_client/sql/stage.py +2 -2
  78. snowflake/ml/model/_client/sql/tag.py +6 -6
  79. snowflake/ml/model/_model_composer/model_composer.py +17 -14
  80. snowflake/ml/model/_model_composer/model_manifest/model_manifest.py +20 -16
  81. snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py +14 -13
  82. snowflake/ml/model/_model_composer/model_method/model_method.py +3 -3
  83. snowflake/ml/model/_packager/model_env/model_env.py +28 -25
  84. snowflake/ml/model/_packager/model_handler.py +4 -4
  85. snowflake/ml/model/_packager/model_handlers/_base.py +2 -2
  86. snowflake/ml/model/_packager/model_handlers/_utils.py +15 -3
  87. snowflake/ml/model/_packager/model_handlers/catboost.py +5 -5
  88. snowflake/ml/model/_packager/model_handlers/custom.py +8 -4
  89. snowflake/ml/model/_packager/model_handlers/huggingface_pipeline.py +7 -21
  90. snowflake/ml/model/_packager/model_handlers/keras.py +4 -4
  91. snowflake/ml/model/_packager/model_handlers/lightgbm.py +4 -14
  92. snowflake/ml/model/_packager/model_handlers/mlflow.py +3 -3
  93. snowflake/ml/model/_packager/model_handlers/pytorch.py +4 -4
  94. snowflake/ml/model/_packager/model_handlers/sentence_transformers.py +5 -5
  95. snowflake/ml/model/_packager/model_handlers/sklearn.py +5 -6
  96. snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +3 -3
  97. snowflake/ml/model/_packager/model_handlers/tensorflow.py +4 -4
  98. snowflake/ml/model/_packager/model_handlers/torchscript.py +4 -4
  99. snowflake/ml/model/_packager/model_handlers/xgboost.py +5 -15
  100. snowflake/ml/model/_packager/model_meta/model_blob_meta.py +2 -2
  101. snowflake/ml/model/_packager/model_meta/model_meta.py +37 -37
  102. snowflake/ml/model/_packager/model_meta/model_meta_schema.py +13 -11
  103. snowflake/ml/model/_packager/model_meta_migrator/base_migrator.py +3 -3
  104. snowflake/ml/model/_packager/model_meta_migrator/migrator_plans.py +3 -3
  105. snowflake/ml/model/_packager/model_meta_migrator/migrator_v1.py +4 -4
  106. snowflake/ml/model/_packager/model_packager.py +11 -9
  107. snowflake/ml/model/_packager/model_runtime/_snowml_inference_alternative_requirements.py +32 -1
  108. snowflake/ml/model/_packager/model_runtime/model_runtime.py +4 -2
  109. snowflake/ml/model/_signatures/core.py +16 -24
  110. snowflake/ml/model/_signatures/dmatrix_handler.py +2 -2
  111. snowflake/ml/model/_signatures/utils.py +6 -6
  112. snowflake/ml/model/custom_model.py +8 -8
  113. snowflake/ml/model/model_signature.py +9 -20
  114. snowflake/ml/model/models/huggingface_pipeline.py +7 -4
  115. snowflake/ml/model/type_hints.py +3 -3
  116. snowflake/ml/modeling/_internal/estimator_utils.py +7 -7
  117. snowflake/ml/modeling/_internal/local_implementations/pandas_handlers.py +6 -6
  118. snowflake/ml/modeling/_internal/local_implementations/pandas_trainer.py +7 -7
  119. snowflake/ml/modeling/_internal/model_specifications.py +8 -10
  120. snowflake/ml/modeling/_internal/model_trainer.py +5 -5
  121. snowflake/ml/modeling/_internal/model_trainer_builder.py +6 -6
  122. snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py +30 -30
  123. snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py +13 -13
  124. snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_trainer.py +31 -31
  125. snowflake/ml/modeling/_internal/snowpark_implementations/xgboost_external_memory_trainer.py +19 -19
  126. snowflake/ml/modeling/_internal/transformer_protocols.py +17 -17
  127. snowflake/ml/modeling/framework/_utils.py +10 -10
  128. snowflake/ml/modeling/framework/base.py +32 -32
  129. snowflake/ml/modeling/impute/__init__.py +1 -1
  130. snowflake/ml/modeling/impute/simple_imputer.py +5 -5
  131. snowflake/ml/modeling/metrics/__init__.py +1 -1
  132. snowflake/ml/modeling/metrics/classification.py +39 -39
  133. snowflake/ml/modeling/metrics/metrics_utils.py +12 -12
  134. snowflake/ml/modeling/metrics/ranking.py +7 -7
  135. snowflake/ml/modeling/metrics/regression.py +13 -13
  136. snowflake/ml/modeling/model_selection/__init__.py +1 -1
  137. snowflake/ml/modeling/model_selection/grid_search_cv.py +7 -7
  138. snowflake/ml/modeling/model_selection/randomized_search_cv.py +7 -7
  139. snowflake/ml/modeling/pipeline/__init__.py +1 -1
  140. snowflake/ml/modeling/pipeline/pipeline.py +18 -18
  141. snowflake/ml/modeling/preprocessing/__init__.py +1 -1
  142. snowflake/ml/modeling/preprocessing/k_bins_discretizer.py +13 -13
  143. snowflake/ml/modeling/preprocessing/max_abs_scaler.py +4 -4
  144. snowflake/ml/modeling/preprocessing/min_max_scaler.py +8 -8
  145. snowflake/ml/modeling/preprocessing/normalizer.py +0 -1
  146. snowflake/ml/modeling/preprocessing/one_hot_encoder.py +28 -28
  147. snowflake/ml/modeling/preprocessing/ordinal_encoder.py +9 -9
  148. snowflake/ml/modeling/preprocessing/robust_scaler.py +7 -7
  149. snowflake/ml/modeling/preprocessing/standard_scaler.py +5 -5
  150. snowflake/ml/monitoring/_client/model_monitor_sql_client.py +26 -26
  151. snowflake/ml/monitoring/_manager/model_monitor_manager.py +5 -5
  152. snowflake/ml/monitoring/entities/model_monitor_config.py +6 -6
  153. snowflake/ml/registry/_manager/model_manager.py +33 -31
  154. snowflake/ml/registry/registry.py +29 -22
  155. snowflake/ml/utils/authentication.py +2 -2
  156. snowflake/ml/utils/connection_params.py +5 -5
  157. snowflake/ml/utils/sparse.py +5 -4
  158. snowflake/ml/utils/sql_client.py +1 -2
  159. snowflake/ml/version.py +2 -1
  160. {snowflake_ml_python-1.8.2.dist-info → snowflake_ml_python-1.8.3.dist-info}/METADATA +16 -7
  161. {snowflake_ml_python-1.8.2.dist-info → snowflake_ml_python-1.8.3.dist-info}/RECORD +164 -166
  162. {snowflake_ml_python-1.8.2.dist-info → snowflake_ml_python-1.8.3.dist-info}/WHEEL +1 -1
  163. snowflake/ml/model/_packager/model_meta/_packaging_requirements.py +0 -1
  164. snowflake/ml/modeling/_internal/constants.py +0 -2
  165. {snowflake_ml_python-1.8.2.dist-info → snowflake_ml_python-1.8.3.dist-info}/licenses/LICENSE.txt +0 -0
  166. {snowflake_ml_python-1.8.2.dist-info → snowflake_ml_python-1.8.3.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
1
1
  import pathlib
2
- from typing import List, Optional, Union
2
+ from typing import Any, Optional, Union, overload
3
3
 
4
4
  import yaml
5
5
 
@@ -19,6 +19,7 @@ class ModelDeploymentSpec:
19
19
  def __init__(self, workspace_path: Optional[pathlib.Path] = None) -> None:
20
20
  self.workspace_path = workspace_path
21
21
 
22
+ @overload
22
23
  def save(
23
24
  self,
24
25
  *,
@@ -26,91 +27,214 @@ class ModelDeploymentSpec:
26
27
  schema_name: sql_identifier.SqlIdentifier,
27
28
  model_name: sql_identifier.SqlIdentifier,
28
29
  version_name: sql_identifier.SqlIdentifier,
29
- service_database_name: Optional[sql_identifier.SqlIdentifier],
30
- service_schema_name: Optional[sql_identifier.SqlIdentifier],
30
+ service_database_name: Optional[sql_identifier.SqlIdentifier] = None,
31
+ service_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
31
32
  service_name: sql_identifier.SqlIdentifier,
33
+ inference_compute_pool_name: sql_identifier.SqlIdentifier,
32
34
  image_build_compute_pool_name: sql_identifier.SqlIdentifier,
33
- service_compute_pool_name: sql_identifier.SqlIdentifier,
34
35
  image_repo_database_name: Optional[sql_identifier.SqlIdentifier],
35
36
  image_repo_schema_name: Optional[sql_identifier.SqlIdentifier],
36
37
  image_repo_name: sql_identifier.SqlIdentifier,
38
+ cpu: Optional[str],
39
+ memory: Optional[str],
40
+ gpu: Optional[Union[str, int]],
41
+ num_workers: Optional[int],
42
+ max_batch_rows: Optional[int],
43
+ force_rebuild: bool,
44
+ external_access_integrations: Optional[list[sql_identifier.SqlIdentifier]],
45
+ # service spec
37
46
  ingress_enabled: bool,
38
47
  max_instances: int,
48
+ ) -> str:
49
+ ...
50
+
51
+ @overload
52
+ def save(
53
+ self,
54
+ *,
55
+ database_name: sql_identifier.SqlIdentifier,
56
+ schema_name: sql_identifier.SqlIdentifier,
57
+ model_name: sql_identifier.SqlIdentifier,
58
+ version_name: sql_identifier.SqlIdentifier,
59
+ job_database_name: Optional[sql_identifier.SqlIdentifier] = None,
60
+ job_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
61
+ job_name: sql_identifier.SqlIdentifier,
62
+ inference_compute_pool_name: sql_identifier.SqlIdentifier,
63
+ image_build_compute_pool_name: sql_identifier.SqlIdentifier,
64
+ image_repo_database_name: Optional[sql_identifier.SqlIdentifier],
65
+ image_repo_schema_name: Optional[sql_identifier.SqlIdentifier],
66
+ image_repo_name: sql_identifier.SqlIdentifier,
67
+ cpu: Optional[str],
68
+ memory: Optional[str],
69
+ gpu: Optional[Union[str, int]],
70
+ num_workers: Optional[int],
71
+ max_batch_rows: Optional[int],
72
+ force_rebuild: bool,
73
+ external_access_integrations: Optional[list[sql_identifier.SqlIdentifier]],
74
+ # job spec
75
+ warehouse: sql_identifier.SqlIdentifier,
76
+ target_method: str,
77
+ input_table_database_name: Optional[sql_identifier.SqlIdentifier] = None,
78
+ input_table_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
79
+ input_table_name: sql_identifier.SqlIdentifier,
80
+ output_table_database_name: Optional[sql_identifier.SqlIdentifier] = None,
81
+ output_table_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
82
+ output_table_name: sql_identifier.SqlIdentifier,
83
+ ) -> str:
84
+ ...
85
+
86
+ def save(
87
+ self,
88
+ *,
89
+ database_name: sql_identifier.SqlIdentifier,
90
+ schema_name: sql_identifier.SqlIdentifier,
91
+ model_name: sql_identifier.SqlIdentifier,
92
+ version_name: sql_identifier.SqlIdentifier,
93
+ service_database_name: Optional[sql_identifier.SqlIdentifier] = None,
94
+ service_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
95
+ service_name: Optional[sql_identifier.SqlIdentifier] = None,
96
+ job_database_name: Optional[sql_identifier.SqlIdentifier] = None,
97
+ job_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
98
+ job_name: Optional[sql_identifier.SqlIdentifier] = None,
99
+ inference_compute_pool_name: sql_identifier.SqlIdentifier,
100
+ image_build_compute_pool_name: sql_identifier.SqlIdentifier,
101
+ image_repo_database_name: Optional[sql_identifier.SqlIdentifier],
102
+ image_repo_schema_name: Optional[sql_identifier.SqlIdentifier],
103
+ image_repo_name: sql_identifier.SqlIdentifier,
39
104
  cpu: Optional[str],
40
105
  memory: Optional[str],
41
106
  gpu: Optional[Union[str, int]],
42
107
  num_workers: Optional[int],
43
108
  max_batch_rows: Optional[int],
44
109
  force_rebuild: bool,
45
- external_access_integrations: Optional[List[sql_identifier.SqlIdentifier]],
110
+ external_access_integrations: Optional[list[sql_identifier.SqlIdentifier]],
111
+ # service spec
112
+ ingress_enabled: Optional[bool] = None,
113
+ max_instances: Optional[int] = None,
114
+ # job spec
115
+ warehouse: Optional[sql_identifier.SqlIdentifier] = None,
116
+ target_method: Optional[str] = None,
117
+ input_table_database_name: Optional[sql_identifier.SqlIdentifier] = None,
118
+ input_table_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
119
+ input_table_name: Optional[sql_identifier.SqlIdentifier] = None,
120
+ output_table_database_name: Optional[sql_identifier.SqlIdentifier] = None,
121
+ output_table_schema_name: Optional[sql_identifier.SqlIdentifier] = None,
122
+ output_table_name: Optional[sql_identifier.SqlIdentifier] = None,
46
123
  ) -> str:
47
124
  # create the deployment spec
48
125
  # models spec
49
126
  fq_model_name = identifier.get_schema_level_object_identifier(
50
127
  database_name.identifier(), schema_name.identifier(), model_name.identifier()
51
128
  )
52
- model_dict = model_deployment_spec_schema.ModelDict(name=fq_model_name, version=version_name.identifier())
129
+ model = model_deployment_spec_schema.Model(name=fq_model_name, version=version_name.identifier())
53
130
 
54
131
  # image_build spec
55
132
  saved_image_repo_database = image_repo_database_name or database_name
56
133
  saved_image_repo_schema = image_repo_schema_name or schema_name
57
134
  fq_image_repo_name = identifier.get_schema_level_object_identifier(
58
- saved_image_repo_database.identifier(), saved_image_repo_schema.identifier(), image_repo_name.identifier()
135
+ db=saved_image_repo_database.identifier(),
136
+ schema=saved_image_repo_schema.identifier(),
137
+ object_name=image_repo_name.identifier(),
59
138
  )
60
- image_build_dict: model_deployment_spec_schema.ImageBuildDict = {
61
- "compute_pool": image_build_compute_pool_name.identifier(),
62
- "image_repo": fq_image_repo_name,
63
- "force_rebuild": force_rebuild,
64
- }
65
- if external_access_integrations is not None:
66
- image_build_dict["external_access_integrations"] = [
67
- eai.identifier() for eai in external_access_integrations
68
- ]
69
139
 
70
- # service spec
71
- saved_service_database = service_database_name or database_name
72
- saved_service_schema = service_schema_name or schema_name
73
- fq_service_name = identifier.get_schema_level_object_identifier(
74
- saved_service_database.identifier(), saved_service_schema.identifier(), service_name.identifier()
140
+ image_build = model_deployment_spec_schema.ImageBuild(
141
+ compute_pool=image_build_compute_pool_name.identifier(),
142
+ image_repo=fq_image_repo_name,
143
+ force_rebuild=force_rebuild,
144
+ external_access_integrations=(
145
+ [eai.identifier() for eai in external_access_integrations] if external_access_integrations else None
146
+ ),
75
147
  )
76
- service_dict = model_deployment_spec_schema.ServiceDict(
77
- name=fq_service_name,
78
- compute_pool=service_compute_pool_name.identifier(),
79
- ingress_enabled=ingress_enabled,
80
- max_instances=max_instances,
81
- )
82
- if cpu:
83
- service_dict["cpu"] = cpu
84
148
 
149
+ # universal base inference spec in service and job
150
+ base_inference_spec: dict[str, Any] = {}
151
+ if cpu:
152
+ base_inference_spec["cpu"] = cpu
85
153
  if memory:
86
- service_dict["memory"] = memory
87
-
154
+ base_inference_spec["memory"] = memory
88
155
  if gpu:
89
156
  if isinstance(gpu, int):
90
157
  gpu_str = str(gpu)
91
158
  else:
92
159
  gpu_str = gpu
93
- service_dict["gpu"] = gpu_str
94
-
160
+ base_inference_spec["gpu"] = gpu_str
95
161
  if num_workers:
96
- service_dict["num_workers"] = num_workers
97
-
162
+ base_inference_spec["num_workers"] = num_workers
98
163
  if max_batch_rows:
99
- service_dict["max_batch_rows"] = max_batch_rows
164
+ base_inference_spec["max_batch_rows"] = max_batch_rows
165
+
166
+ if service_name: # service spec
167
+ assert ingress_enabled, "ingress_enabled is required for service spec"
168
+ assert max_instances, "max_instances is required for service spec"
169
+ saved_service_database = service_database_name or database_name
170
+ saved_service_schema = service_schema_name or schema_name
171
+ fq_service_name = identifier.get_schema_level_object_identifier(
172
+ saved_service_database.identifier(), saved_service_schema.identifier(), service_name.identifier()
173
+ )
174
+ service = model_deployment_spec_schema.Service(
175
+ name=fq_service_name,
176
+ compute_pool=inference_compute_pool_name.identifier(),
177
+ ingress_enabled=ingress_enabled,
178
+ max_instances=max_instances,
179
+ **base_inference_spec,
180
+ )
181
+
182
+ # model deployment spec
183
+ model_deployment_spec: Union[
184
+ model_deployment_spec_schema.ModelServiceDeploymentSpec,
185
+ model_deployment_spec_schema.ModelJobDeploymentSpec,
186
+ ] = model_deployment_spec_schema.ModelServiceDeploymentSpec(
187
+ models=[model],
188
+ image_build=image_build,
189
+ service=service,
190
+ )
191
+ else: # job spec
192
+ assert job_name, "job_name is required for job spec"
193
+ assert warehouse, "warehouse is required for job spec"
194
+ assert target_method, "target_method is required for job spec"
195
+ assert input_table_name, "input_table_name is required for job spec"
196
+ assert output_table_name, "output_table_name is required for job spec"
197
+ saved_job_database = job_database_name or database_name
198
+ saved_job_schema = job_schema_name or schema_name
199
+ input_table_database_name = input_table_database_name or database_name
200
+ input_table_schema_name = input_table_schema_name or schema_name
201
+ output_table_database_name = output_table_database_name or database_name
202
+ output_table_schema_name = output_table_schema_name or schema_name
203
+ fq_job_name = identifier.get_schema_level_object_identifier(
204
+ saved_job_database.identifier(), saved_job_schema.identifier(), job_name.identifier()
205
+ )
206
+ fq_input_table_name = identifier.get_schema_level_object_identifier(
207
+ input_table_database_name.identifier(),
208
+ input_table_schema_name.identifier(),
209
+ input_table_name.identifier(),
210
+ )
211
+ fq_output_table_name = identifier.get_schema_level_object_identifier(
212
+ output_table_database_name.identifier(),
213
+ output_table_schema_name.identifier(),
214
+ output_table_name.identifier(),
215
+ )
216
+ job = model_deployment_spec_schema.Job(
217
+ name=fq_job_name,
218
+ compute_pool=inference_compute_pool_name.identifier(),
219
+ warehouse=warehouse.identifier(),
220
+ target_method=target_method,
221
+ input_table_name=fq_input_table_name,
222
+ output_table_name=fq_output_table_name,
223
+ **base_inference_spec,
224
+ )
225
+
226
+ # model deployment spec
227
+ model_deployment_spec = model_deployment_spec_schema.ModelJobDeploymentSpec(
228
+ models=[model],
229
+ image_build=image_build,
230
+ job=job,
231
+ )
100
232
 
101
- # model deployment spec
102
- model_deployment_spec_dict = model_deployment_spec_schema.ModelDeploymentSpecDict(
103
- models=[model_dict],
104
- image_build=image_build_dict,
105
- service=service_dict,
106
- )
107
-
108
- # Anchors are not supported in the server, avoid that.
109
- yaml.SafeDumper.ignore_aliases = lambda *args: True # type: ignore[method-assign]
110
233
  if self.workspace_path is None:
111
- return yaml.safe_dump(model_deployment_spec_dict)
234
+ return yaml.safe_dump(model_deployment_spec.model_dump(exclude_none=True))
235
+
112
236
  # save the yaml
113
237
  file_path = self.workspace_path / self.DEPLOY_SPEC_FILE_REL_PATH
114
238
  with file_path.open("w", encoding="utf-8") as f:
115
- yaml.safe_dump(model_deployment_spec_dict, f)
239
+ yaml.safe_dump(model_deployment_spec.model_dump(exclude_none=True), f)
116
240
  return str(file_path.resolve())
@@ -1,33 +1,53 @@
1
- from typing import List, TypedDict
1
+ from typing import Optional
2
2
 
3
- from typing_extensions import NotRequired, Required
3
+ from pydantic import BaseModel
4
4
 
5
5
 
6
- class ModelDict(TypedDict):
7
- name: Required[str]
8
- version: Required[str]
6
+ class Model(BaseModel):
7
+ name: str
8
+ version: str
9
9
 
10
10
 
11
- class ImageBuildDict(TypedDict):
12
- compute_pool: Required[str]
13
- image_repo: Required[str]
14
- force_rebuild: Required[bool]
15
- external_access_integrations: NotRequired[List[str]]
11
+ class ImageBuild(BaseModel):
12
+ compute_pool: str
13
+ image_repo: str
14
+ force_rebuild: bool
15
+ external_access_integrations: Optional[list[str]] = None
16
16
 
17
17
 
18
- class ServiceDict(TypedDict):
19
- name: Required[str]
20
- compute_pool: Required[str]
21
- ingress_enabled: Required[bool]
22
- max_instances: Required[int]
23
- cpu: NotRequired[str]
24
- memory: NotRequired[str]
25
- gpu: NotRequired[str]
26
- num_workers: NotRequired[int]
27
- max_batch_rows: NotRequired[int]
18
+ class Service(BaseModel):
19
+ name: str
20
+ compute_pool: str
21
+ ingress_enabled: bool
22
+ max_instances: int
23
+ cpu: Optional[str] = None
24
+ memory: Optional[str] = None
25
+ gpu: Optional[str] = None
26
+ num_workers: Optional[int] = None
27
+ max_batch_rows: Optional[int] = None
28
28
 
29
29
 
30
- class ModelDeploymentSpecDict(TypedDict):
31
- models: Required[List[ModelDict]]
32
- image_build: Required[ImageBuildDict]
33
- service: Required[ServiceDict]
30
+ class Job(BaseModel):
31
+ name: str
32
+ compute_pool: str
33
+ cpu: Optional[str] = None
34
+ memory: Optional[str] = None
35
+ gpu: Optional[str] = None
36
+ num_workers: Optional[int] = None
37
+ max_batch_rows: Optional[int] = None
38
+ warehouse: str
39
+ target_method: str
40
+ input_table_name: str
41
+ output_table_name: str
42
+
43
+
44
+ class ModelServiceDeploymentSpec(BaseModel):
45
+ models: list[Model]
46
+ image_build: ImageBuild
47
+ service: Service
48
+
49
+
50
+ class ModelJobDeploymentSpec(BaseModel):
51
+ models: list[Model]
52
+ image_build: ImageBuild
53
+ job: Job
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List, Optional
1
+ from typing import Any, Optional
2
2
 
3
3
  from snowflake.ml._internal.utils import query_result_checker, sql_identifier
4
4
  from snowflake.ml.model._client.sql import _base
@@ -24,8 +24,8 @@ class ModelSQLClient(_base._BaseSQLClient):
24
24
  schema_name: Optional[sql_identifier.SqlIdentifier],
25
25
  model_name: Optional[sql_identifier.SqlIdentifier] = None,
26
26
  validate_result: bool = True,
27
- statement_params: Optional[Dict[str, Any]] = None,
28
- ) -> List[row.Row]:
27
+ statement_params: Optional[dict[str, Any]] = None,
28
+ ) -> list[row.Row]:
29
29
  actual_database_name = database_name or self._database_name
30
30
  actual_schema_name = schema_name or self._schema_name
31
31
  fully_qualified_schema_name = ".".join([actual_database_name.identifier(), actual_schema_name.identifier()])
@@ -57,8 +57,8 @@ class ModelSQLClient(_base._BaseSQLClient):
57
57
  version_name: Optional[sql_identifier.SqlIdentifier] = None,
58
58
  validate_result: bool = True,
59
59
  check_model_details: bool = False,
60
- statement_params: Optional[Dict[str, Any]] = None,
61
- ) -> List[row.Row]:
60
+ statement_params: Optional[dict[str, Any]] = None,
61
+ ) -> list[row.Row]:
62
62
  like_sql = ""
63
63
  if version_name:
64
64
  like_sql = f" LIKE '{version_name.resolved()}'"
@@ -90,7 +90,7 @@ class ModelSQLClient(_base._BaseSQLClient):
90
90
  schema_name: Optional[sql_identifier.SqlIdentifier],
91
91
  model_name: sql_identifier.SqlIdentifier,
92
92
  comment: str,
93
- statement_params: Optional[Dict[str, Any]] = None,
93
+ statement_params: Optional[dict[str, Any]] = None,
94
94
  ) -> None:
95
95
  query_result_checker.SqlResultValidator(
96
96
  self._session,
@@ -107,7 +107,7 @@ class ModelSQLClient(_base._BaseSQLClient):
107
107
  database_name: Optional[sql_identifier.SqlIdentifier],
108
108
  schema_name: Optional[sql_identifier.SqlIdentifier],
109
109
  model_name: sql_identifier.SqlIdentifier,
110
- statement_params: Optional[Dict[str, Any]] = None,
110
+ statement_params: Optional[dict[str, Any]] = None,
111
111
  ) -> None:
112
112
  query_result_checker.SqlResultValidator(
113
113
  self._session,
@@ -124,7 +124,7 @@ class ModelSQLClient(_base._BaseSQLClient):
124
124
  new_model_db: Optional[sql_identifier.SqlIdentifier],
125
125
  new_model_schema: Optional[sql_identifier.SqlIdentifier],
126
126
  new_model_name: sql_identifier.SqlIdentifier,
127
- statement_params: Optional[Dict[str, Any]] = None,
127
+ statement_params: Optional[dict[str, Any]] = None,
128
128
  ) -> None:
129
129
  # Use registry's database and schema if a non fully qualified new model name is provided.
130
130
  new_fully_qualified_name = self.fully_qualified_object_name(new_model_db, new_model_schema, new_model_name)
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import pathlib
3
3
  import textwrap
4
- from typing import Any, Dict, List, Optional, Tuple
4
+ from typing import Any, Optional
5
5
  from urllib.parse import ParseResult
6
6
 
7
7
  from snowflake.ml._internal.utils import (
@@ -34,7 +34,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
34
34
  model_name: sql_identifier.SqlIdentifier,
35
35
  version_name: sql_identifier.SqlIdentifier,
36
36
  stage_path: str,
37
- statement_params: Optional[Dict[str, Any]] = None,
37
+ statement_params: Optional[dict[str, Any]] = None,
38
38
  ) -> None:
39
39
  query_result_checker.SqlResultValidator(
40
40
  self._session,
@@ -56,7 +56,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
56
56
  schema_name: Optional[sql_identifier.SqlIdentifier],
57
57
  model_name: sql_identifier.SqlIdentifier,
58
58
  version_name: sql_identifier.SqlIdentifier,
59
- statement_params: Optional[Dict[str, Any]] = None,
59
+ statement_params: Optional[dict[str, Any]] = None,
60
60
  ) -> None:
61
61
  fq_source_model_name = self.fully_qualified_object_name(
62
62
  source_database_name, source_schema_name, source_model_name
@@ -78,7 +78,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
78
78
  schema_name: Optional[sql_identifier.SqlIdentifier],
79
79
  model_name: sql_identifier.SqlIdentifier,
80
80
  version_name: sql_identifier.SqlIdentifier,
81
- statement_params: Optional[Dict[str, Any]] = None,
81
+ statement_params: Optional[dict[str, Any]] = None,
82
82
  ) -> None:
83
83
  sql = (
84
84
  f"CREATE MODEL {self.fully_qualified_object_name(database_name, schema_name, model_name)}"
@@ -97,7 +97,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
97
97
  schema_name: Optional[sql_identifier.SqlIdentifier],
98
98
  model_name: sql_identifier.SqlIdentifier,
99
99
  version_name: sql_identifier.SqlIdentifier,
100
- statement_params: Optional[Dict[str, Any]] = None,
100
+ statement_params: Optional[dict[str, Any]] = None,
101
101
  ) -> None:
102
102
  sql = (
103
103
  f"ALTER MODEL {self.fully_qualified_object_name(database_name, schema_name, model_name)}"
@@ -116,7 +116,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
116
116
  schema_name: Optional[sql_identifier.SqlIdentifier],
117
117
  model_name: sql_identifier.SqlIdentifier,
118
118
  version_name: sql_identifier.SqlIdentifier,
119
- statement_params: Optional[Dict[str, Any]] = None,
119
+ statement_params: Optional[dict[str, Any]] = None,
120
120
  ) -> None:
121
121
  sql = (
122
122
  f"ALTER MODEL {self.fully_qualified_object_name(database_name, schema_name, model_name)}"
@@ -138,7 +138,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
138
138
  model_name: sql_identifier.SqlIdentifier,
139
139
  version_name: sql_identifier.SqlIdentifier,
140
140
  stage_path: str,
141
- statement_params: Optional[Dict[str, Any]] = None,
141
+ statement_params: Optional[dict[str, Any]] = None,
142
142
  ) -> None:
143
143
  query_result_checker.SqlResultValidator(
144
144
  self._session,
@@ -160,7 +160,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
160
160
  schema_name: Optional[sql_identifier.SqlIdentifier],
161
161
  model_name: sql_identifier.SqlIdentifier,
162
162
  version_name: sql_identifier.SqlIdentifier,
163
- statement_params: Optional[Dict[str, Any]] = None,
163
+ statement_params: Optional[dict[str, Any]] = None,
164
164
  ) -> None:
165
165
  fq_source_model_name = self.fully_qualified_object_name(
166
166
  source_database_name, source_schema_name, source_model_name
@@ -182,7 +182,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
182
182
  schema_name: Optional[sql_identifier.SqlIdentifier],
183
183
  model_name: sql_identifier.SqlIdentifier,
184
184
  version_name: sql_identifier.SqlIdentifier,
185
- statement_params: Optional[Dict[str, Any]] = None,
185
+ statement_params: Optional[dict[str, Any]] = None,
186
186
  ) -> None:
187
187
  query_result_checker.SqlResultValidator(
188
188
  self._session,
@@ -201,7 +201,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
201
201
  model_name: sql_identifier.SqlIdentifier,
202
202
  version_name: sql_identifier.SqlIdentifier,
203
203
  alias_name: sql_identifier.SqlIdentifier,
204
- statement_params: Optional[Dict[str, Any]] = None,
204
+ statement_params: Optional[dict[str, Any]] = None,
205
205
  ) -> None:
206
206
  query_result_checker.SqlResultValidator(
207
207
  self._session,
@@ -219,7 +219,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
219
219
  schema_name: Optional[sql_identifier.SqlIdentifier],
220
220
  model_name: sql_identifier.SqlIdentifier,
221
221
  version_or_alias_name: sql_identifier.SqlIdentifier,
222
- statement_params: Optional[Dict[str, Any]] = None,
222
+ statement_params: Optional[dict[str, Any]] = None,
223
223
  ) -> None:
224
224
  query_result_checker.SqlResultValidator(
225
225
  self._session,
@@ -239,8 +239,8 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
239
239
  version_name: sql_identifier.SqlIdentifier,
240
240
  file_path: pathlib.PurePosixPath,
241
241
  is_dir: bool = False,
242
- statement_params: Optional[Dict[str, Any]] = None,
243
- ) -> List[row.Row]:
242
+ statement_params: Optional[dict[str, Any]] = None,
243
+ ) -> list[row.Row]:
244
244
  # Workaround for snowURL bug.
245
245
  trailing_slash = "/" if is_dir else ""
246
246
 
@@ -276,7 +276,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
276
276
  version_name: sql_identifier.SqlIdentifier,
277
277
  file_path: pathlib.PurePosixPath,
278
278
  target_path: pathlib.Path,
279
- statement_params: Optional[Dict[str, Any]] = None,
279
+ statement_params: Optional[dict[str, Any]] = None,
280
280
  ) -> pathlib.Path:
281
281
  stage_location = pathlib.PurePosixPath(
282
282
  self.fully_qualified_object_name(database_name, schema_name, model_name),
@@ -310,8 +310,8 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
310
310
  schema_name: Optional[sql_identifier.SqlIdentifier],
311
311
  model_name: sql_identifier.SqlIdentifier,
312
312
  version_name: sql_identifier.SqlIdentifier,
313
- statement_params: Optional[Dict[str, Any]] = None,
314
- ) -> List[row.Row]:
313
+ statement_params: Optional[dict[str, Any]] = None,
314
+ ) -> list[row.Row]:
315
315
  res = query_result_checker.SqlResultValidator(
316
316
  self._session,
317
317
  (
@@ -331,7 +331,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
331
331
  model_name: sql_identifier.SqlIdentifier,
332
332
  version_name: sql_identifier.SqlIdentifier,
333
333
  comment: str,
334
- statement_params: Optional[Dict[str, Any]] = None,
334
+ statement_params: Optional[dict[str, Any]] = None,
335
335
  ) -> None:
336
336
  query_result_checker.SqlResultValidator(
337
337
  self._session,
@@ -351,9 +351,9 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
351
351
  version_name: sql_identifier.SqlIdentifier,
352
352
  method_name: sql_identifier.SqlIdentifier,
353
353
  input_df: dataframe.DataFrame,
354
- input_args: List[sql_identifier.SqlIdentifier],
355
- returns: List[Tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
356
- statement_params: Optional[Dict[str, Any]] = None,
354
+ input_args: list[sql_identifier.SqlIdentifier],
355
+ returns: list[tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
356
+ statement_params: Optional[dict[str, Any]] = None,
357
357
  ) -> dataframe.DataFrame:
358
358
  with_statements = []
359
359
  if len(input_df.queries["queries"]) == 1 and len(input_df.queries["post_actions"]) == 0:
@@ -433,10 +433,10 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
433
433
  version_name: sql_identifier.SqlIdentifier,
434
434
  method_name: sql_identifier.SqlIdentifier,
435
435
  input_df: dataframe.DataFrame,
436
- input_args: List[sql_identifier.SqlIdentifier],
437
- returns: List[Tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
436
+ input_args: list[sql_identifier.SqlIdentifier],
437
+ returns: list[tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
438
438
  partition_column: Optional[sql_identifier.SqlIdentifier],
439
- statement_params: Optional[Dict[str, Any]] = None,
439
+ statement_params: Optional[dict[str, Any]] = None,
440
440
  is_partitioned: bool = True,
441
441
  ) -> dataframe.DataFrame:
442
442
  with_statements = []
@@ -529,13 +529,13 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
529
529
 
530
530
  def set_metadata(
531
531
  self,
532
- metadata_dict: Dict[str, Any],
532
+ metadata_dict: dict[str, Any],
533
533
  *,
534
534
  database_name: Optional[sql_identifier.SqlIdentifier],
535
535
  schema_name: Optional[sql_identifier.SqlIdentifier],
536
536
  model_name: sql_identifier.SqlIdentifier,
537
537
  version_name: sql_identifier.SqlIdentifier,
538
- statement_params: Optional[Dict[str, Any]] = None,
538
+ statement_params: Optional[dict[str, Any]] = None,
539
539
  ) -> None:
540
540
  json_metadata = json.dumps(metadata_dict)
541
541
  query_result_checker.SqlResultValidator(
@@ -554,7 +554,7 @@ class ModelVersionSQLClient(_base._BaseSQLClient):
554
554
  schema_name: Optional[sql_identifier.SqlIdentifier],
555
555
  model_name: sql_identifier.SqlIdentifier,
556
556
  version_name: sql_identifier.SqlIdentifier,
557
- statement_params: Optional[Dict[str, Any]] = None,
557
+ statement_params: Optional[dict[str, Any]] = None,
558
558
  ) -> None:
559
559
  query_result_checker.SqlResultValidator(
560
560
  self._session,
@@ -1,7 +1,7 @@
1
1
  import enum
2
2
  import json
3
3
  import textwrap
4
- from typing import Any, Dict, List, Optional, Tuple, Union
4
+ from typing import Any, Optional, Union
5
5
 
6
6
  from snowflake import snowpark
7
7
  from snowflake.ml._internal import platform_capabilities
@@ -47,7 +47,7 @@ class ServiceSQLClient(_base._BaseSQLClient):
47
47
  gpu: Optional[Union[str, int]],
48
48
  force_rebuild: bool,
49
49
  external_access_integration: sql_identifier.SqlIdentifier,
50
- statement_params: Optional[Dict[str, Any]] = None,
50
+ statement_params: Optional[dict[str, Any]] = None,
51
51
  ) -> None:
52
52
  actual_image_repo_database = image_repo_database_name or self._database_name
53
53
  actual_image_repo_schema = image_repo_schema_name or self._schema_name
@@ -76,8 +76,8 @@ class ServiceSQLClient(_base._BaseSQLClient):
76
76
  stage_path: Optional[str] = None,
77
77
  model_deployment_spec_yaml_str: Optional[str] = None,
78
78
  model_deployment_spec_file_rel_path: Optional[str] = None,
79
- statement_params: Optional[Dict[str, Any]] = None,
80
- ) -> Tuple[str, snowpark.AsyncJob]:
79
+ statement_params: Optional[dict[str, Any]] = None,
80
+ ) -> tuple[str, snowpark.AsyncJob]:
81
81
  assert model_deployment_spec_yaml_str or model_deployment_spec_file_rel_path
82
82
  if model_deployment_spec_yaml_str:
83
83
  sql_str = f"CALL SYSTEM$DEPLOY_MODEL('{model_deployment_spec_yaml_str}')"
@@ -95,9 +95,9 @@ class ServiceSQLClient(_base._BaseSQLClient):
95
95
  service_name: sql_identifier.SqlIdentifier,
96
96
  method_name: sql_identifier.SqlIdentifier,
97
97
  input_df: dataframe.DataFrame,
98
- input_args: List[sql_identifier.SqlIdentifier],
99
- returns: List[Tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
100
- statement_params: Optional[Dict[str, Any]] = None,
98
+ input_args: list[sql_identifier.SqlIdentifier],
99
+ returns: list[tuple[str, spt.DataType, sql_identifier.SqlIdentifier]],
100
+ statement_params: Optional[dict[str, Any]] = None,
101
101
  ) -> dataframe.DataFrame:
102
102
  with_statements = []
103
103
  actual_database_name = database_name or self._database_name
@@ -181,7 +181,7 @@ class ServiceSQLClient(_base._BaseSQLClient):
181
181
  service_name: sql_identifier.SqlIdentifier,
182
182
  instance_id: str = "0",
183
183
  container_name: str,
184
- statement_params: Optional[Dict[str, Any]] = None,
184
+ statement_params: Optional[dict[str, Any]] = None,
185
185
  ) -> str:
186
186
  system_func = "SYSTEM$GET_SERVICE_LOGS"
187
187
  rows = (
@@ -206,8 +206,8 @@ class ServiceSQLClient(_base._BaseSQLClient):
206
206
  schema_name: Optional[sql_identifier.SqlIdentifier],
207
207
  service_name: sql_identifier.SqlIdentifier,
208
208
  include_message: bool = False,
209
- statement_params: Optional[Dict[str, Any]] = None,
210
- ) -> Tuple[ServiceStatus, Optional[str]]:
209
+ statement_params: Optional[dict[str, Any]] = None,
210
+ ) -> tuple[ServiceStatus, Optional[str]]:
211
211
  system_func = "SYSTEM$GET_SERVICE_STATUS"
212
212
  rows = (
213
213
  query_result_checker.SqlResultValidator(
@@ -231,7 +231,7 @@ class ServiceSQLClient(_base._BaseSQLClient):
231
231
  database_name: Optional[sql_identifier.SqlIdentifier],
232
232
  schema_name: Optional[sql_identifier.SqlIdentifier],
233
233
  service_name: sql_identifier.SqlIdentifier,
234
- statement_params: Optional[Dict[str, Any]] = None,
234
+ statement_params: Optional[dict[str, Any]] = None,
235
235
  ) -> None:
236
236
  query_result_checker.SqlResultValidator(
237
237
  self._session,
@@ -245,8 +245,8 @@ class ServiceSQLClient(_base._BaseSQLClient):
245
245
  database_name: Optional[sql_identifier.SqlIdentifier],
246
246
  schema_name: Optional[sql_identifier.SqlIdentifier],
247
247
  service_name: sql_identifier.SqlIdentifier,
248
- statement_params: Optional[Dict[str, Any]] = None,
249
- ) -> List[row.Row]:
248
+ statement_params: Optional[dict[str, Any]] = None,
249
+ ) -> list[row.Row]:
250
250
  fully_qualified_service_name = self.fully_qualified_object_name(database_name, schema_name, service_name)
251
251
  res = (
252
252
  query_result_checker.SqlResultValidator(