sql-testing-library 0.10.1__tar.gz → 0.11.0__tar.gz

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 (22) hide show
  1. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/CHANGELOG.md +6 -0
  2. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/PKG-INFO +3 -4
  3. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/README.md +2 -3
  4. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/pyproject.toml +1 -1
  5. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/snowflake.py +31 -1
  6. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_sql_utils.py +9 -0
  7. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/LICENSE +0 -0
  8. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/__init__.py +0 -0
  9. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/__init__.py +0 -0
  10. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/athena.py +0 -0
  11. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/base.py +0 -0
  12. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/bigquery.py +0 -0
  13. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/presto.py +0 -0
  14. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/redshift.py +0 -0
  15. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_adapters/trino.py +0 -0
  16. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_core.py +0 -0
  17. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_exceptions.py +0 -0
  18. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_mock_table.py +0 -0
  19. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_pytest_plugin.py +0 -0
  20. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_sql_logger.py +0 -0
  21. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/_types.py +0 -0
  22. {sql_testing_library-0.10.1 → sql_testing_library-0.11.0}/src/sql_testing_library/py.typed +0 -0
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## 0.11.0 (2025-06-16)
9
+
10
+ ### Feat
11
+
12
+ - **snowflake**: ad support for map datatype in snowflake (#101)
13
+
8
14
  ## 0.10.1 (2025-06-15)
9
15
 
10
16
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sql-testing-library
3
- Version: 0.10.1
3
+ Version: 0.11.0
4
4
  Summary: A powerful Python framework for unit testing SQL queries across BigQuery, Snowflake, Redshift, Athena, and Trino with mock data
5
5
  License: MIT
6
6
  Keywords: sql,testing,unit-testing,mock-data,database-testing,bigquery,snowflake,redshift,athena,trino,data-engineering,etl-testing,sql-validation,query-testing
@@ -136,7 +136,7 @@ The library supports different data types across database engines. All checkmark
136
136
  | **Integer Array** | `List[int]` | ✅ | ✅ | ✅ | ✅ | ✅ |
137
137
  | **Decimal Array** | `List[Decimal]` | ✅ | ✅ | ✅ | ✅ | ✅ |
138
138
  | **Optional Array** | `Optional[List[T]]` | ✅ | ✅ | ✅ | ✅ | ✅ |
139
- | **Map/Dict** | `Dict[K, V]` | ✅ | ✅ | ✅ | ✅ | |
139
+ | **Map/Dict** | `Dict[K, V]` | ✅ | ✅ | ✅ | ✅ | |
140
140
  | **Struct/Record** | `dataclass` | ❌ | ❌ | ❌ | ❌ | ❌ |
141
141
  | **Nested Arrays** | `List[List[T]]` | ❌ | ❌ | ❌ | ❌ | ❌ |
142
142
 
@@ -146,7 +146,7 @@ The library supports different data types across database engines. All checkmark
146
146
  - **Athena**: 256KB query size limit; supports arrays and maps using `ARRAY[]` and `MAP(ARRAY[], ARRAY[])` syntax
147
147
  - **Redshift**: Arrays and maps implemented via SUPER type (JSON parsing); 16MB query size limit
148
148
  - **Trino**: Memory catalog for testing; excellent decimal precision; supports arrays and maps
149
- - **Snowflake**: Column names normalized to lowercase; 1MB query size limit
149
+ - **Snowflake**: Column names normalized to lowercase; 1MB query size limit; dict/map types implemented via VARIANT type (JSON parsing)
150
150
 
151
151
  ## Execution Modes Support
152
152
 
@@ -1048,7 +1048,6 @@ The library has a few known limitations that are planned to be addressed in futu
1048
1048
 
1049
1049
  ### Snowflake Support
1050
1050
  - Physical table tests for Snowflake are currently skipped due to complex mocking requirements
1051
- - Need better support for Snowflake-specific data types (VARIANT, OBJECT, ARRAY)
1052
1051
 
1053
1052
  ### General Improvements
1054
1053
  - Add support for more SQL dialects
@@ -79,7 +79,7 @@ The library supports different data types across database engines. All checkmark
79
79
  | **Integer Array** | `List[int]` | ✅ | ✅ | ✅ | ✅ | ✅ |
80
80
  | **Decimal Array** | `List[Decimal]` | ✅ | ✅ | ✅ | ✅ | ✅ |
81
81
  | **Optional Array** | `Optional[List[T]]` | ✅ | ✅ | ✅ | ✅ | ✅ |
82
- | **Map/Dict** | `Dict[K, V]` | ✅ | ✅ | ✅ | ✅ | |
82
+ | **Map/Dict** | `Dict[K, V]` | ✅ | ✅ | ✅ | ✅ | |
83
83
  | **Struct/Record** | `dataclass` | ❌ | ❌ | ❌ | ❌ | ❌ |
84
84
  | **Nested Arrays** | `List[List[T]]` | ❌ | ❌ | ❌ | ❌ | ❌ |
85
85
 
@@ -89,7 +89,7 @@ The library supports different data types across database engines. All checkmark
89
89
  - **Athena**: 256KB query size limit; supports arrays and maps using `ARRAY[]` and `MAP(ARRAY[], ARRAY[])` syntax
90
90
  - **Redshift**: Arrays and maps implemented via SUPER type (JSON parsing); 16MB query size limit
91
91
  - **Trino**: Memory catalog for testing; excellent decimal precision; supports arrays and maps
92
- - **Snowflake**: Column names normalized to lowercase; 1MB query size limit
92
+ - **Snowflake**: Column names normalized to lowercase; 1MB query size limit; dict/map types implemented via VARIANT type (JSON parsing)
93
93
 
94
94
  ## Execution Modes Support
95
95
 
@@ -991,7 +991,6 @@ The library has a few known limitations that are planned to be addressed in futu
991
991
 
992
992
  ### Snowflake Support
993
993
  - Physical table tests for Snowflake are currently skipped due to complex mocking requirements
994
- - Need better support for Snowflake-specific data types (VARIANT, OBJECT, ARRAY)
995
994
 
996
995
  ### General Improvements
997
996
  - Add support for more SQL dialects
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "sql-testing-library"
7
- version = "0.10.1"
7
+ version = "0.11.0"
8
8
  description = "A powerful Python framework for unit testing SQL queries across BigQuery, Snowflake, Redshift, Athena, and Trino with mock data"
9
9
  authors = ["Gurmeet Saran <gurmeetx@gmail.com>", "Kushal Thakkar <kushal.thakkar@gmail.com>"]
10
10
  maintainers = ["Gurmeet Saran <gurmeetx@gmail.com>", "Kushal Thakkar <kushal.thakkar@gmail.com>"]
@@ -30,6 +30,32 @@ class SnowflakeTypeConverter(BaseTypeConverter):
30
30
 
31
31
  def convert(self, value: Any, target_type: Type) -> Any:
32
32
  """Convert Snowflake result value to target type."""
33
+ # Handle None/NULL values first
34
+ if value is None:
35
+ return None
36
+
37
+ # Handle Optional types
38
+ if self.is_optional_type(target_type):
39
+ if value is None:
40
+ return None
41
+ target_type = self.get_optional_inner_type(target_type)
42
+
43
+ # Handle dict/map types from Snowflake VARIANT columns
44
+ if hasattr(target_type, "__origin__") and target_type.__origin__ is dict:
45
+ # Snowflake returns VARIANT types as Python dicts already
46
+ if isinstance(value, dict):
47
+ return value
48
+ # If it's a string, parse it
49
+ elif isinstance(value, str):
50
+ import json
51
+
52
+ try:
53
+ return json.loads(value)
54
+ except json.JSONDecodeError:
55
+ return {}
56
+ else:
57
+ return {}
58
+
33
59
  # Snowflake returns proper Python types in most cases, so use base converter
34
60
  return super().convert(value, target_type)
35
61
 
@@ -248,7 +274,11 @@ class SnowflakeAdapter(DatabaseAdapter):
248
274
  if non_none_types:
249
275
  col_type = non_none_types[0]
250
276
 
251
- snowflake_type = type_mapping.get(col_type, "VARCHAR")
277
+ # Handle dict/map types
278
+ if hasattr(col_type, "__origin__") and col_type.__origin__ is dict:
279
+ snowflake_type = "VARIANT"
280
+ else:
281
+ snowflake_type = type_mapping.get(col_type, "VARCHAR")
252
282
  column_defs.append(f'"{col_name}" {snowflake_type}')
253
283
 
254
284
  columns_sql = ",\n ".join(column_defs)
@@ -170,6 +170,9 @@ def format_sql_value(value: Any, column_type: Type, dialect: str = "standard") -
170
170
  elif dialect == "bigquery":
171
171
  # BigQuery JSON type handles NULL maps
172
172
  return "NULL"
173
+ elif dialect == "snowflake":
174
+ # Snowflake VARIANT type handles NULL maps
175
+ return "NULL::VARIANT"
173
176
  else:
174
177
  return "NULL"
175
178
 
@@ -298,6 +301,12 @@ def format_sql_value(value: Any, column_type: Type, dialect: str = "standard") -
298
301
  # Escape single quotes in JSON string for SQL
299
302
  json_str = json_str.replace("'", "''")
300
303
  return f"'{json_str}'"
304
+ elif dialect == "snowflake":
305
+ # Snowflake uses VARIANT type with PARSE_JSON function
306
+ json_str = json.dumps(value, cls=DecimalEncoder)
307
+ # Escape single quotes in JSON string for SQL
308
+ json_str = json_str.replace("'", "''")
309
+ return f"PARSE_JSON('{json_str}')"
301
310
  else:
302
311
  # Other databases don't have native map support yet
303
312
  raise NotImplementedError(f"Map type not yet supported for dialect: {dialect}")