sql-testing-library 0.23.1__tar.gz → 0.24.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 (24) hide show
  1. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/CHANGELOG.md +6 -0
  2. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/PKG-INFO +2 -4
  3. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/README.md +0 -1
  4. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/pyproject.toml +3 -4
  5. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/__init__.py +1 -1
  6. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_core.py +12 -8
  7. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/LICENSE +0 -0
  8. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/__init__.py +0 -0
  9. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/athena.py +0 -0
  10. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/base.py +0 -0
  11. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/bigquery.py +0 -0
  12. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/clickhouse.py +0 -0
  13. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/duckdb.py +0 -0
  14. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/presto.py +0 -0
  15. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/redshift.py +0 -0
  16. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/snowflake.py +0 -0
  17. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_adapters/trino.py +0 -0
  18. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_exceptions.py +0 -0
  19. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_mock_table.py +0 -0
  20. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_pytest_plugin.py +0 -0
  21. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_sql_logger.py +0 -0
  22. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_sql_utils.py +0 -0
  23. {sql_testing_library-0.23.1 → sql_testing_library-0.24.0}/src/sql_testing_library/_types.py +0 -0
  24. {sql_testing_library-0.23.1 → sql_testing_library-0.24.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.24.0 (2026-11-09)
9
+
10
+ ### Fix
11
+
12
+ - **core**: keep NULL results as None under pandas 3 (#213)
13
+
8
14
  ## 0.23.1 (2026-10-02)
9
15
 
10
16
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql-testing-library
3
- Version: 0.23.1
3
+ Version: 0.24.0
4
4
  Summary: SQL Testing Framework for Python: Unit test SQL queries with mock data injection for BigQuery, Snowflake, Redshift, Athena, Trino, DuckDB, and ClickHouse. Simplify data engineering ETL testing and analytics validation.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -9,7 +9,7 @@ Author: Gurmeet Saran
9
9
  Author-email: gurmeetx@gmail.com
10
10
  Maintainer: Gurmeet Saran
11
11
  Maintainer-email: gurmeetx@gmail.com
12
- Requires-Python: >=3.10
12
+ Requires-Python: >=3.11
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Environment :: Console
15
15
  Classifier: Framework :: Pytest
@@ -20,7 +20,6 @@ Classifier: License :: OSI Approved :: MIT License
20
20
  Classifier: Natural Language :: English
21
21
  Classifier: Operating System :: OS Independent
22
22
  Classifier: Programming Language :: Python :: 3
23
- Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
25
24
  Classifier: Programming Language :: Python :: 3.12
26
25
  Classifier: Programming Language :: Python :: 3.13
@@ -1266,7 +1265,6 @@ tox
1266
1265
 
1267
1266
  # Test specific Python version
1268
1267
  tox -e py39 # Python 3.9
1269
- tox -e py310 # Python 3.10
1270
1268
  tox -e py311 # Python 3.11
1271
1269
  tox -e py312 # Python 3.12
1272
1270
  ```
@@ -1206,7 +1206,6 @@ tox
1206
1206
 
1207
1207
  # Test specific Python version
1208
1208
  tox -e py39 # Python 3.9
1209
- tox -e py310 # Python 3.10
1210
1209
  tox -e py311 # Python 3.11
1211
1210
  tox -e py312 # Python 3.12
1212
1211
  ```
@@ -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.23.1"
7
+ version = "0.24.0"
8
8
  description = "SQL Testing Framework for Python: Unit test SQL queries with mock data injection for BigQuery, Snowflake, Redshift, Athena, Trino, DuckDB, and ClickHouse. Simplify data engineering ETL testing and analytics validation."
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>"]
@@ -59,7 +59,6 @@ classifiers = [
59
59
  "Topic :: Scientific/Engineering :: Information Analysis",
60
60
  "License :: OSI Approved :: MIT License",
61
61
  "Programming Language :: Python :: 3",
62
- "Programming Language :: Python :: 3.10",
63
62
  "Programming Language :: Python :: 3.11",
64
63
  "Programming Language :: Python :: 3.12",
65
64
  "Programming Language :: Python :: Implementation :: CPython",
@@ -84,7 +83,7 @@ include = ["LICENSE", "README.md", "CHANGELOG.md", "py.typed", "src/sql_testing_
84
83
  "Contributing" = "https://github.com/gurmeetsaran/sqltesting/blob/master/CONTRIBUTING.md"
85
84
 
86
85
  [tool.poetry.dependencies]
87
- python = ">=3.10"
86
+ python = ">=3.11"
88
87
  sqlglot = ">=26.0.0"
89
88
  pydantic = ">=2.0.0"
90
89
  pandas = ">=1.0.0"
@@ -145,7 +144,7 @@ mocksmith = ">=6.0.1"
145
144
  sql_testing = "sql_testing_library._pytest_plugin"
146
145
 
147
146
  [tool.pyright]
148
- pythonVersion = "3.10"
147
+ pythonVersion = "3.11"
149
148
  include = ["src"]
150
149
  exclude = ["tests", "scripts"]
151
150
  reportMissingImports = true
@@ -27,7 +27,7 @@ try:
27
27
  except ImportError:
28
28
  __all__ = []
29
29
 
30
- __version__ = "0.23.1"
30
+ __version__ = "0.24.0"
31
31
  __all__.extend(
32
32
  [
33
33
  "SQLTestFramework",
@@ -892,29 +892,33 @@ class SQLTestFramework:
892
892
 
893
893
  def _deserialize_results(self, result_df: "pd.DataFrame", result_class: Type[T]) -> List[T]:
894
894
  """Deserialize query results to typed objects."""
895
- import numpy as np
896
-
897
895
  if result_df.empty:
898
896
  return []
899
897
 
900
- # STEP 1: Convert database-returned NaN values to Python None
898
+ # STEP 1: Convert database-returned missing values (NaN / NA / NaT) to Python None
901
899
  #
902
900
  # WHY THIS IS NEEDED:
903
- # - SQL databases return NULL values which pandas converts to NaN
904
- # - Different database adapters may return NaN for null numeric/float columns
905
- # - NaN values break object serialization (dataclass/Pydantic instantiation)
901
+ # - SQL databases return NULL values which pandas stores as NaN/NA/NaT
902
+ # - Missing-value sentinels break object serialization (dataclass/Pydantic instantiation)
906
903
  # - Python None is the correct representation for nullable/optional fields
907
904
  #
905
+ # WHY astype(object) + where, AND to_dict() INSTEAD OF iterrows():
906
+ # - pandas 3 infers its dedicated string dtype for all-string data and stores
907
+ # missing values there as NaN, never None. Adapters such as Athena return every
908
+ # column as strings, so a plain replace() is undone as soon as iterrows() rebuilds
909
+ # each row as a Series and re-infers the string dtype.
910
+ # - Forcing plain object dtype and iterating dict records keeps None intact.
911
+ #
908
912
  # RELATIONSHIP TO mock_table.py NaN HANDLING:
909
913
  # - mock_table.py: Handles NaN created during DataFrame dtype conversion (input side)
910
914
  # - core.py (here): Handles NaN returned from actual database queries (output side)
911
915
  # - Both are needed because NaN can appear at different pipeline stages
912
- result_df = result_df.replace([np.nan], [None])
916
+ result_df = result_df.astype(object).where(result_df.notna(), None)
913
917
  # Get type hints from the result class
914
918
  type_hints = get_type_hints(result_class)
915
919
 
916
920
  results: List[T] = []
917
- for _, row in result_df.iterrows():
921
+ for row in result_df.to_dict(orient="records"):
918
922
  # Convert row to dictionary with proper types
919
923
  converted_row: Dict[str, Any] = {}
920
924
  for col_name, value in row.items():