sqlalchemy-seerdb 0.2.1__tar.gz → 0.2.2__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 (19) hide show
  1. {sqlalchemy_seerdb-0.2.1/sqlalchemy_seerdb.egg-info → sqlalchemy_seerdb-0.2.2}/PKG-INFO +1 -1
  2. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/pyproject.toml +1 -1
  3. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb/__init__.py +1 -1
  4. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb/seerdb.py +27 -3
  5. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2/sqlalchemy_seerdb.egg-info}/PKG-INFO +1 -1
  6. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb.egg-info/SOURCES.txt +1 -0
  7. sqlalchemy_seerdb-0.2.2/test/test_boolean.py +32 -0
  8. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/LICENSES/MIT.txt +0 -0
  9. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/README.md +0 -0
  10. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/setup.cfg +0 -0
  11. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb/provision.py +0 -0
  12. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb/requirements.py +0 -0
  13. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb.egg-info/dependency_links.txt +0 -0
  14. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb.egg-info/entry_points.txt +0 -0
  15. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb.egg-info/requires.txt +0 -0
  16. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/sqlalchemy_seerdb.egg-info/top_level.txt +0 -0
  17. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/test/test_connect_args.py +0 -0
  18. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/test/test_suite.py +0 -0
  19. {sqlalchemy_seerdb-0.2.1 → sqlalchemy_seerdb-0.2.2}/test/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlalchemy-seerdb
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: SQLAlchemy dialect for the seerdb driver
5
5
  Author-email: Peter Lemenkov <lemenkov@gmail.com>
6
6
  License-Expression: MIT
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "sqlalchemy-seerdb"
10
- version = "0.2.1"
10
+ version = "0.2.2"
11
11
  description = "SQLAlchemy dialect for the seerdb driver"
12
12
  readme = "README.md"
13
13
  license = "MIT"
@@ -19,4 +19,4 @@ from sqlalchemy_seerdb.seerdb import SeerdbDialect
19
19
 
20
20
  __all__ = ['SeerdbDialect', '__version__']
21
21
 
22
- __version__ = '0.2.1'
22
+ __version__ = '0.2.2'
@@ -32,7 +32,7 @@ from sqlalchemy.dialects.oracle.base import (
32
32
  OracleDialect,
33
33
  OracleExecutionContext,
34
34
  )
35
- from sqlalchemy.dialects.oracle.types import _OracleDate
35
+ from sqlalchemy.dialects.oracle.types import _OracleBoolean, _OracleDate
36
36
  from sqlalchemy.engine import cursor as _cursor
37
37
  from sqlalchemy.engine import interfaces
38
38
 
@@ -72,6 +72,25 @@ class _SeerdbDate(_OracleDate):
72
72
  return process
73
73
 
74
74
 
75
+ class _SeerdbBoolean(_OracleBoolean):
76
+ """A `Boolean` column read back as a `bool`.
77
+
78
+ Before 23ai there is no BOOLEAN type, so the column is a NUMBER and the
79
+ driver reads 1 or 0 back as a number. From SQLAlchemy 2.1 the generic
80
+ dialect leaves the conversion to an output type handler that only the
81
+ drivers it ships with install, so here it is taken as it is for `Date`. A
82
+ native BOOLEAN already arrives as a `bool` and passes through.
83
+ """
84
+
85
+ def result_processor(self, dialect, coltype):
86
+ def process(value):
87
+ if value is None or isinstance(value, bool):
88
+ return value
89
+ return bool(value)
90
+
91
+ return process
92
+
93
+
75
94
  class SeerdbExecutionContext(OracleExecutionContext):
76
95
  """Turns this backend's RETURNING into the rows SQLAlchemy expects.
77
96
 
@@ -288,8 +307,13 @@ class SeerdbDialect(OracleDialect):
288
307
  # no processor either way, so a Float column came back holding a Decimal.
289
308
  supports_native_decimal = True
290
309
 
291
- # As the base dialect's, plus the date narrowing above.
292
- colspecs: ClassVar[dict] = {**_oracle_base.colspecs, sqltypes.Date: _SeerdbDate}
310
+ # As the base dialect's, plus the date narrowing and the boolean
311
+ # conversion above.
312
+ colspecs: ClassVar[dict] = {
313
+ **_oracle_base.colspecs,
314
+ sqltypes.Date: _SeerdbDate,
315
+ sqltypes.Boolean: _SeerdbBoolean,
316
+ }
293
317
 
294
318
  # No SQL is generated differently from the base dialect, so cached
295
319
  # statements stay valid.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlalchemy-seerdb
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: SQLAlchemy dialect for the seerdb driver
5
5
  Author-email: Peter Lemenkov <lemenkov@gmail.com>
6
6
  License-Expression: MIT
@@ -11,6 +11,7 @@ sqlalchemy_seerdb.egg-info/dependency_links.txt
11
11
  sqlalchemy_seerdb.egg-info/entry_points.txt
12
12
  sqlalchemy_seerdb.egg-info/requires.txt
13
13
  sqlalchemy_seerdb.egg-info/top_level.txt
14
+ test/test_boolean.py
14
15
  test/test_connect_args.py
15
16
  test/test_suite.py
16
17
  test/test_version.py
@@ -0,0 +1,32 @@
1
+ # SPDX-FileCopyrightText: 2026 Peter Lemenkov <lemenkov@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """A Boolean column comes back as a bool whatever the driver returns."""
5
+
6
+ import unittest
7
+
8
+ from sqlalchemy import types as sqltypes
9
+
10
+ from sqlalchemy_seerdb.seerdb import SeerdbDialect, _SeerdbBoolean
11
+
12
+
13
+ class TestBoolean(unittest.TestCase):
14
+ def setUp(self):
15
+ self.process = _SeerdbBoolean().result_processor(SeerdbDialect(), None)
16
+
17
+ def test_a_number_becomes_a_bool(self):
18
+ # Before 23ai the column is a NUMBER, and the driver reads 1 / 0.
19
+ self.assertIs(self.process(1), True)
20
+ self.assertIs(self.process(0), False)
21
+
22
+ def test_a_native_bool_and_a_null_pass_through(self):
23
+ self.assertIs(self.process(True), True)
24
+ self.assertIs(self.process(False), False)
25
+ self.assertIsNone(self.process(None))
26
+
27
+ def test_the_dialect_uses_it_for_boolean(self):
28
+ self.assertIs(SeerdbDialect.colspecs[sqltypes.Boolean], _SeerdbBoolean)
29
+
30
+
31
+ if __name__ == '__main__':
32
+ unittest.main()