sqlspec 0.4.0__tar.gz → 0.5.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.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- {sqlspec-0.4.0 → sqlspec-0.5.0}/.pre-commit-config.yaml +2 -2
- {sqlspec-0.4.0 → sqlspec-0.5.0}/Makefile +9 -18
- sqlspec-0.5.0/PKG-INFO +126 -0
- sqlspec-0.5.0/README.md +75 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/pyproject.toml +2 -2
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/_serialization.py +1 -1
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/_typing.py +31 -1
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/adbc/config.py +7 -7
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/aiosqlite/config.py +2 -2
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/asyncmy/config.py +9 -4
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/asyncpg/config.py +12 -8
- sqlspec-0.5.0/sqlspec/adapters/duckdb/__init__.py +3 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/duckdb/config.py +15 -14
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/oracledb/__init__.py +1 -1
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/oracledb/config/_asyncio.py +6 -3
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/oracledb/config/_common.py +7 -7
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/oracledb/config/_sync.py +7 -4
- sqlspec-0.5.0/sqlspec/adapters/psycopg/config/__init__.py +9 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/psycopg/config/_async.py +6 -3
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/psycopg/config/_common.py +3 -3
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/psycopg/config/_sync.py +6 -3
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/sqlite/config.py +3 -3
- sqlspec-0.5.0/sqlspec/base.py +87 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/filters.py +2 -1
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/typing.py +119 -31
- sqlspec-0.5.0/sqlspec/utils/deprecation.py +111 -0
- sqlspec-0.5.0/sqlspec/utils/fixtures.py +66 -0
- sqlspec-0.5.0/sqlspec/utils/module_loader.py +94 -0
- sqlspec-0.5.0/sqlspec/utils/text.py +46 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/unit/test_adapters/test_duckdb/test_config.py +7 -5
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/unit/test_typing.py +12 -12
- sqlspec-0.5.0/tests/unit/test_utils/test_module_loader.py +47 -0
- sqlspec-0.5.0/tests/unit/test_utils/test_text.py +16 -0
- sqlspec-0.5.0/tools/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/uv.lock +635 -636
- sqlspec-0.4.0/PKG-INFO +0 -84
- sqlspec-0.4.0/README.md +0 -33
- sqlspec-0.4.0/sqlspec/adapters/psycopg/config/__init__.py +0 -9
- sqlspec-0.4.0/sqlspec/config.py +0 -16
- {sqlspec-0.4.0 → sqlspec-0.5.0}/.gitignore +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/CONTRIBUTING.rst +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/NOTICE +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/__metadata__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/adbc/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/asyncmy/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/asyncpg/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/adapters/oracledb/config/__init__.py +0 -0
- {sqlspec-0.4.0/sqlspec/adapters/duckdb → sqlspec-0.5.0/sqlspec/adapters/psycopg}/__init__.py +0 -0
- {sqlspec-0.4.0/sqlspec/adapters/psycopg → sqlspec-0.5.0/sqlspec/adapters/sqlite}/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/exceptions.py +0 -0
- {sqlspec-0.4.0/sqlspec/adapters/sqlite → sqlspec-0.5.0/sqlspec/extensions}/__init__.py +0 -0
- {sqlspec-0.4.0/sqlspec/extensions → sqlspec-0.5.0/sqlspec/extensions/litestar}/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/extensions/litestar/plugin.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/sqlspec/py.typed +0 -0
- {sqlspec-0.4.0/sqlspec/extensions/litestar → sqlspec-0.5.0/sqlspec/utils}/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/conftest.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/unit/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/unit/test_adapters/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tests/unit/test_adapters/test_duckdb/__init__.py +0 -0
- {sqlspec-0.4.0/tools → sqlspec-0.5.0/tests/unit/test_utils}/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tools/build_docs.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tools/pypi_readme.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tools/sphinx_ext/__init__.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tools/sphinx_ext/changelog.py +0 -0
- {sqlspec-0.4.0 → sqlspec-0.5.0}/tools/sphinx_ext/missing_references.py +0 -0
|
@@ -2,7 +2,7 @@ default_language_version:
|
|
|
2
2
|
python: "3"
|
|
3
3
|
repos:
|
|
4
4
|
- repo: https://github.com/compilerla/conventional-pre-commit
|
|
5
|
-
rev:
|
|
5
|
+
rev: v4.0.0
|
|
6
6
|
hooks:
|
|
7
7
|
- id: conventional-pre-commit
|
|
8
8
|
stages: [commit-msg]
|
|
@@ -17,7 +17,7 @@ repos:
|
|
|
17
17
|
- id: mixed-line-ending
|
|
18
18
|
- id: trailing-whitespace
|
|
19
19
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
|
20
|
-
rev: "v0.
|
|
20
|
+
rev: "v0.9.1"
|
|
21
21
|
hooks:
|
|
22
22
|
- id: ruff
|
|
23
23
|
args: ["--fix"]
|
|
@@ -121,45 +121,36 @@ test: ## Run the tests
|
|
|
121
121
|
@uv run pytest tests
|
|
122
122
|
@echo "${OK} Tests complete ✨"
|
|
123
123
|
|
|
124
|
-
.PHONY: test-examples
|
|
125
|
-
test-examples: ## Run the examples tests
|
|
126
|
-
@echo "${INFO} Running example tests... 🧪"
|
|
127
|
-
@uv run pytest docs/examples
|
|
128
|
-
@echo "${OK} Example tests complete ✨"
|
|
129
|
-
|
|
130
124
|
.PHONY: test-all
|
|
131
|
-
test-all:
|
|
125
|
+
test-all: tests ## Run all tests
|
|
132
126
|
@echo "${INFO} All tests executed successfully ✨"
|
|
133
127
|
|
|
134
128
|
.PHONY: coverage
|
|
135
|
-
coverage:
|
|
129
|
+
coverage: ## Run tests with coverage report
|
|
136
130
|
@echo "${INFO} Running tests with coverage... 📊"
|
|
137
|
-
@uv run pytest
|
|
131
|
+
@uv run pytest --cov -n auto --quiet
|
|
138
132
|
@uv run coverage html >/dev/null 2>&1
|
|
139
133
|
@uv run coverage xml >/dev/null 2>&1
|
|
140
134
|
@echo "${OK} Coverage report generated ✨"
|
|
141
135
|
|
|
136
|
+
# -----------------------------------------------------------------------------
|
|
137
|
+
# Type Checking
|
|
138
|
+
# -----------------------------------------------------------------------------
|
|
139
|
+
|
|
142
140
|
.PHONY: mypy
|
|
143
141
|
mypy: ## Run mypy
|
|
144
142
|
@echo "${INFO} Running mypy... 🔍"
|
|
145
143
|
@uv run dmypy run
|
|
146
|
-
@echo "${OK}
|
|
147
|
-
|
|
148
|
-
.PHONY: mypy-nocache
|
|
149
|
-
mypy-nocache: ## Run Mypy without cache
|
|
150
|
-
@echo "${INFO} Running mypy without cache... 🔍"
|
|
151
|
-
@uv run mypy
|
|
152
|
-
@echo "${OK} mypy complete ✨"
|
|
144
|
+
@echo "${OK} Mypy checks passed ✨"
|
|
153
145
|
|
|
154
146
|
.PHONY: pyright
|
|
155
147
|
pyright: ## Run pyright
|
|
156
148
|
@echo "${INFO} Running pyright... 🔍"
|
|
157
149
|
@uv run pyright
|
|
158
|
-
@echo "${OK}
|
|
150
|
+
@echo "${OK} Pyright checks passed ✨"
|
|
159
151
|
|
|
160
152
|
.PHONY: type-check
|
|
161
153
|
type-check: mypy pyright ## Run all type checking
|
|
162
|
-
@echo "${OK} All type checks passed ✨"
|
|
163
154
|
|
|
164
155
|
# -----------------------------------------------------------------------------
|
|
165
156
|
# Linting and Formatting
|
sqlspec-0.5.0/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sqlspec
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: SQL Experiments in Python
|
|
5
|
+
Author-email: Cody Fincher <cody@litestar.dev>
|
|
6
|
+
Maintainer-email: Litestar Developers <hello@litestar.dev>
|
|
7
|
+
License-File: NOTICE
|
|
8
|
+
Requires-Python: <4.0,>=3.9
|
|
9
|
+
Requires-Dist: eval-type-backport; python_version < '3.10'
|
|
10
|
+
Requires-Dist: sqlglot
|
|
11
|
+
Requires-Dist: typing-extensions
|
|
12
|
+
Provides-Extra: adbc
|
|
13
|
+
Requires-Dist: adbc-driver-manager; extra == 'adbc'
|
|
14
|
+
Requires-Dist: pyarrow; extra == 'adbc'
|
|
15
|
+
Provides-Extra: aioodbc
|
|
16
|
+
Requires-Dist: aioodbc; extra == 'aioodbc'
|
|
17
|
+
Provides-Extra: aiosqlite
|
|
18
|
+
Requires-Dist: aiosqlite; extra == 'aiosqlite'
|
|
19
|
+
Provides-Extra: asyncmy
|
|
20
|
+
Requires-Dist: asyncmy; extra == 'asyncmy'
|
|
21
|
+
Provides-Extra: asyncpg
|
|
22
|
+
Requires-Dist: asyncpg; extra == 'asyncpg'
|
|
23
|
+
Provides-Extra: bigquery
|
|
24
|
+
Requires-Dist: google-cloud-bigquery; extra == 'bigquery'
|
|
25
|
+
Provides-Extra: duckdb
|
|
26
|
+
Requires-Dist: duckdb; extra == 'duckdb'
|
|
27
|
+
Provides-Extra: fastapi
|
|
28
|
+
Requires-Dist: fastapi; extra == 'fastapi'
|
|
29
|
+
Provides-Extra: flask
|
|
30
|
+
Requires-Dist: flask; extra == 'flask'
|
|
31
|
+
Provides-Extra: litestar
|
|
32
|
+
Requires-Dist: litestar; extra == 'litestar'
|
|
33
|
+
Provides-Extra: msgspec
|
|
34
|
+
Requires-Dist: msgspec; extra == 'msgspec'
|
|
35
|
+
Provides-Extra: oracledb
|
|
36
|
+
Requires-Dist: oracledb; extra == 'oracledb'
|
|
37
|
+
Provides-Extra: performance
|
|
38
|
+
Requires-Dist: google-re2; (sys_platform == 'linux') and extra == 'performance'
|
|
39
|
+
Requires-Dist: sqlglot[rs]; extra == 'performance'
|
|
40
|
+
Provides-Extra: psycopg
|
|
41
|
+
Requires-Dist: psycopg[binary,pool]; extra == 'psycopg'
|
|
42
|
+
Provides-Extra: pydantic
|
|
43
|
+
Requires-Dist: pydantic; extra == 'pydantic'
|
|
44
|
+
Provides-Extra: pymssql
|
|
45
|
+
Requires-Dist: pymssql; extra == 'pymssql'
|
|
46
|
+
Provides-Extra: pymysql
|
|
47
|
+
Requires-Dist: pymysql; extra == 'pymysql'
|
|
48
|
+
Provides-Extra: spanner
|
|
49
|
+
Requires-Dist: google-cloud-spanner; extra == 'spanner'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
# SQLSpec
|
|
53
|
+
|
|
54
|
+
## A Query Mapper for Python
|
|
55
|
+
|
|
56
|
+
SQLSpec is an experimental Python library designed to streamline and modernize your SQL interactions across a variety of database systems. While still in its early stages, SQLSpec aims to provide a flexible, typed, and extensible interface for working with SQL in Python.
|
|
57
|
+
|
|
58
|
+
**Note**: SQLSpec is currently under active development and the API is subject to change. It is not yet ready for production use. Contributions are welcome!
|
|
59
|
+
|
|
60
|
+
### Core Features (Planned but subject to change, removal or redesign)
|
|
61
|
+
|
|
62
|
+
- **Consistent Database Session Interface**: Provides a consistent connectivity interface for interacting with one or more database systems, including SQLite, Postgres, DuckDB, MySQL, Oracle, SQL Server, Spanner, BigQuery, and more.
|
|
63
|
+
- **Emphasis on RAW SQL and Minimal Abstractions and Performance**: SQLSpec is a library for working with SQL in Python. It's goals are to offer minimal abstractions between the user and the database. It does not aim to be an ORM library.
|
|
64
|
+
- **Type-Safe Queries**: Quickly map SQL queries to typed objects using libraries such as Pydantic, Msqgspec, Attrs, etc.
|
|
65
|
+
- **Extensible Design**: Easily add support for new database dialects or extend existing functionality to meet your specific needs. Easily add support for async and sync database drivers.
|
|
66
|
+
- **Minimal Dependencies**: SQLSpec is designed to be lightweight and can run on it's own or with other libraries such as `litestar`, `fastapi`, `flask` and more. (Contributions welcome!)
|
|
67
|
+
- **Dynamic Query Manipulation**: Easily apply filters to pre-defined queries with a fluent, Pythonic API. Safely manipulate queries without the risk of SQL injection.
|
|
68
|
+
- **Dialect Validation and Conversion**: Use `sqlglot` to validate your SQL against specific dialects and seamlessly convert between them.
|
|
69
|
+
- **Support for Async and Sync Database Drivers**: SQLSpec supports both async and sync database drivers, allowing you to choose the style that best fits your application.
|
|
70
|
+
|
|
71
|
+
### What SQLSpec Is Not (Yet)
|
|
72
|
+
|
|
73
|
+
SQLSpec is a work in progress. While it offers a solid foundation for modern SQL interactions, it does not yet include every feature you might find in a mature ORM or database toolkit. The focus is on building a robust, flexible core that can be extended over time.
|
|
74
|
+
|
|
75
|
+
### Inspiration and Future Direction
|
|
76
|
+
|
|
77
|
+
SQLSpec originally drew inspiration from features found in the `aiosql` library. This is a great library for working with and executed SQL stored in files. It's unclear how much of an overlap there will be between the two libraries, but it's possible that some features will be contributed back to `aiosql` where appropriate.
|
|
78
|
+
|
|
79
|
+
### Current Focus: Universal Connectivity
|
|
80
|
+
|
|
81
|
+
The primary goal at this stage is to establish a **native connectivity interface** that works seamlessly across all supported database environments. This means you can connect to any of the supported databases using a consistent API, regardless of the underlying driver or dialect.
|
|
82
|
+
|
|
83
|
+
### Adapters: Completed, In Progress, and Planned
|
|
84
|
+
|
|
85
|
+
This list is not final. If you have a driver you'd like to see added, please open an issue or submit a PR!
|
|
86
|
+
|
|
87
|
+
| Driver | Database | Mode | Status |
|
|
88
|
+
| :----------------------------------------------------------------------------------------------------------- | :--------- | :------ | :--------- |
|
|
89
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | Postgres | Sync | ✅ |
|
|
90
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | SQLite | Sync | ✅ |
|
|
91
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | Snowflake | Sync | ✅ |
|
|
92
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | DuckDB | Sync | ✅ |
|
|
93
|
+
| [`asyncpg`](https://magicstack.github.io/asyncpg/current/) | PostgreSQL | Async | ✅ |
|
|
94
|
+
| [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Sync | ✅ |
|
|
95
|
+
| [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Async | ✅ |
|
|
96
|
+
| [`aiosqlite`](https://github.com/omnilib/aiosqlite) | SQLite | Async | ✅ |
|
|
97
|
+
| `sqlite3` | SQLite | Sync | ✅ |
|
|
98
|
+
| [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Async | ✅ |
|
|
99
|
+
| [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Sync | ✅ |
|
|
100
|
+
| [`duckdb`](https://duckdb.org/) | DuckDB | Sync | ✅ |
|
|
101
|
+
| [`bigquery`](https://googleapis.dev/python/bigquery/latest/index.html) | BigQuery | Sync | 🗓️ Planned |
|
|
102
|
+
| [`spanner`](https://googleapis.dev/python/spanner/latest/index.html) | Spanner | Sync | 🗓️ Planned |
|
|
103
|
+
| [`sqlserver`](https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-for-pyodbc?view=sql-server-ver16) | SQL Server | Sync | 🗓️ Planned |
|
|
104
|
+
| [`mysql`](https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-python.html) | MySQL | Sync | 🗓️ Planned |
|
|
105
|
+
| [`snowflake`](https://docs.snowflake.com)
|
|
106
|
+
|
|
107
|
+
### Proposed Project Structure
|
|
108
|
+
|
|
109
|
+
- `sqlspec/`:
|
|
110
|
+
- `adapters/`: Contains all database drivers and associated configuration.
|
|
111
|
+
- `extensions/`:
|
|
112
|
+
- `litestar/`: Future home of `litestar` integration.
|
|
113
|
+
- `fastapi/`: Future home of `fastapi` integration.
|
|
114
|
+
- `flask/`: Future home of `flask` integration.
|
|
115
|
+
- `*/`: Future home of your favorite framework integration 🔌 ✨
|
|
116
|
+
- `base.py`: Contains base protocols for database configurations.
|
|
117
|
+
- `filters.py`: Contains the `Filter` class which is used to apply filters to pre-defined SQL queries.
|
|
118
|
+
- `utils/`: Contains utility functions used throughout the project.
|
|
119
|
+
- `exceptions.py`: Contains custom exceptions for SQLSpec.
|
|
120
|
+
- `typing.py`: Contains type hints, type guards and several facades for optional libraries that are not required for the core functionality of SQLSpec.
|
|
121
|
+
|
|
122
|
+
### Get Involved
|
|
123
|
+
|
|
124
|
+
SQLSpec is an open-source project, and contributions are welcome! Whether you're interested in adding support for new databases, improving the query interface, or simply providing feedback, your input is valuable.
|
|
125
|
+
|
|
126
|
+
**Disclaimer**: SQLSpec is under active development. Expect changes and improvements as the project evolves.
|
sqlspec-0.5.0/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# SQLSpec
|
|
2
|
+
|
|
3
|
+
## A Query Mapper for Python
|
|
4
|
+
|
|
5
|
+
SQLSpec is an experimental Python library designed to streamline and modernize your SQL interactions across a variety of database systems. While still in its early stages, SQLSpec aims to provide a flexible, typed, and extensible interface for working with SQL in Python.
|
|
6
|
+
|
|
7
|
+
**Note**: SQLSpec is currently under active development and the API is subject to change. It is not yet ready for production use. Contributions are welcome!
|
|
8
|
+
|
|
9
|
+
### Core Features (Planned but subject to change, removal or redesign)
|
|
10
|
+
|
|
11
|
+
- **Consistent Database Session Interface**: Provides a consistent connectivity interface for interacting with one or more database systems, including SQLite, Postgres, DuckDB, MySQL, Oracle, SQL Server, Spanner, BigQuery, and more.
|
|
12
|
+
- **Emphasis on RAW SQL and Minimal Abstractions and Performance**: SQLSpec is a library for working with SQL in Python. It's goals are to offer minimal abstractions between the user and the database. It does not aim to be an ORM library.
|
|
13
|
+
- **Type-Safe Queries**: Quickly map SQL queries to typed objects using libraries such as Pydantic, Msqgspec, Attrs, etc.
|
|
14
|
+
- **Extensible Design**: Easily add support for new database dialects or extend existing functionality to meet your specific needs. Easily add support for async and sync database drivers.
|
|
15
|
+
- **Minimal Dependencies**: SQLSpec is designed to be lightweight and can run on it's own or with other libraries such as `litestar`, `fastapi`, `flask` and more. (Contributions welcome!)
|
|
16
|
+
- **Dynamic Query Manipulation**: Easily apply filters to pre-defined queries with a fluent, Pythonic API. Safely manipulate queries without the risk of SQL injection.
|
|
17
|
+
- **Dialect Validation and Conversion**: Use `sqlglot` to validate your SQL against specific dialects and seamlessly convert between them.
|
|
18
|
+
- **Support for Async and Sync Database Drivers**: SQLSpec supports both async and sync database drivers, allowing you to choose the style that best fits your application.
|
|
19
|
+
|
|
20
|
+
### What SQLSpec Is Not (Yet)
|
|
21
|
+
|
|
22
|
+
SQLSpec is a work in progress. While it offers a solid foundation for modern SQL interactions, it does not yet include every feature you might find in a mature ORM or database toolkit. The focus is on building a robust, flexible core that can be extended over time.
|
|
23
|
+
|
|
24
|
+
### Inspiration and Future Direction
|
|
25
|
+
|
|
26
|
+
SQLSpec originally drew inspiration from features found in the `aiosql` library. This is a great library for working with and executed SQL stored in files. It's unclear how much of an overlap there will be between the two libraries, but it's possible that some features will be contributed back to `aiosql` where appropriate.
|
|
27
|
+
|
|
28
|
+
### Current Focus: Universal Connectivity
|
|
29
|
+
|
|
30
|
+
The primary goal at this stage is to establish a **native connectivity interface** that works seamlessly across all supported database environments. This means you can connect to any of the supported databases using a consistent API, regardless of the underlying driver or dialect.
|
|
31
|
+
|
|
32
|
+
### Adapters: Completed, In Progress, and Planned
|
|
33
|
+
|
|
34
|
+
This list is not final. If you have a driver you'd like to see added, please open an issue or submit a PR!
|
|
35
|
+
|
|
36
|
+
| Driver | Database | Mode | Status |
|
|
37
|
+
| :----------------------------------------------------------------------------------------------------------- | :--------- | :------ | :--------- |
|
|
38
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | Postgres | Sync | ✅ |
|
|
39
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | SQLite | Sync | ✅ |
|
|
40
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | Snowflake | Sync | ✅ |
|
|
41
|
+
| [`adbc`](https://arrow.apache.org/adbc/) | DuckDB | Sync | ✅ |
|
|
42
|
+
| [`asyncpg`](https://magicstack.github.io/asyncpg/current/) | PostgreSQL | Async | ✅ |
|
|
43
|
+
| [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Sync | ✅ |
|
|
44
|
+
| [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Async | ✅ |
|
|
45
|
+
| [`aiosqlite`](https://github.com/omnilib/aiosqlite) | SQLite | Async | ✅ |
|
|
46
|
+
| `sqlite3` | SQLite | Sync | ✅ |
|
|
47
|
+
| [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Async | ✅ |
|
|
48
|
+
| [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Sync | ✅ |
|
|
49
|
+
| [`duckdb`](https://duckdb.org/) | DuckDB | Sync | ✅ |
|
|
50
|
+
| [`bigquery`](https://googleapis.dev/python/bigquery/latest/index.html) | BigQuery | Sync | 🗓️ Planned |
|
|
51
|
+
| [`spanner`](https://googleapis.dev/python/spanner/latest/index.html) | Spanner | Sync | 🗓️ Planned |
|
|
52
|
+
| [`sqlserver`](https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-for-pyodbc?view=sql-server-ver16) | SQL Server | Sync | 🗓️ Planned |
|
|
53
|
+
| [`mysql`](https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-python.html) | MySQL | Sync | 🗓️ Planned |
|
|
54
|
+
| [`snowflake`](https://docs.snowflake.com)
|
|
55
|
+
|
|
56
|
+
### Proposed Project Structure
|
|
57
|
+
|
|
58
|
+
- `sqlspec/`:
|
|
59
|
+
- `adapters/`: Contains all database drivers and associated configuration.
|
|
60
|
+
- `extensions/`:
|
|
61
|
+
- `litestar/`: Future home of `litestar` integration.
|
|
62
|
+
- `fastapi/`: Future home of `fastapi` integration.
|
|
63
|
+
- `flask/`: Future home of `flask` integration.
|
|
64
|
+
- `*/`: Future home of your favorite framework integration 🔌 ✨
|
|
65
|
+
- `base.py`: Contains base protocols for database configurations.
|
|
66
|
+
- `filters.py`: Contains the `Filter` class which is used to apply filters to pre-defined SQL queries.
|
|
67
|
+
- `utils/`: Contains utility functions used throughout the project.
|
|
68
|
+
- `exceptions.py`: Contains custom exceptions for SQLSpec.
|
|
69
|
+
- `typing.py`: Contains type hints, type guards and several facades for optional libraries that are not required for the core functionality of SQLSpec.
|
|
70
|
+
|
|
71
|
+
### Get Involved
|
|
72
|
+
|
|
73
|
+
SQLSpec is an open-source project, and contributions are welcome! Whether you're interested in adding support for new databases, improving the query interface, or simply providing feedback, your input is valuable.
|
|
74
|
+
|
|
75
|
+
**Disclaimer**: SQLSpec is under active development. Expect changes and improvements as the project evolves.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
authors = [{ name = "Cody Fincher", email = "cody@litestar.dev" }]
|
|
3
|
-
dependencies = ["typing-extensions
|
|
3
|
+
dependencies = ["typing-extensions", "sqlglot", "eval_type_backport; python_version < \"3.10\""]
|
|
4
4
|
description = "SQL Experiments in Python"
|
|
5
5
|
maintainers = [{ name = "Litestar Developers", email = "hello@litestar.dev" }]
|
|
6
6
|
name = "sqlspec"
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
requires-python = ">=3.9, <4.0"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.5.0"
|
|
10
10
|
|
|
11
11
|
[project.optional-dependencies]
|
|
12
12
|
adbc = ["adbc-driver-manager", "pyarrow"]
|
|
@@ -13,7 +13,7 @@ try:
|
|
|
13
13
|
|
|
14
14
|
except ImportError:
|
|
15
15
|
try:
|
|
16
|
-
from orjson import dumps as _encode_json # pyright: ignore[reportMissingImports]
|
|
16
|
+
from orjson import dumps as _encode_json # pyright: ignore[reportMissingImports,reportUnknownVariableType]
|
|
17
17
|
from orjson import loads as decode_json # type: ignore[no-redef]
|
|
18
18
|
|
|
19
19
|
def encode_json(data: Any) -> str:
|
|
@@ -29,7 +29,6 @@ class DataclassProtocol(Protocol):
|
|
|
29
29
|
T = TypeVar("T")
|
|
30
30
|
T_co = TypeVar("T_co", covariant=True)
|
|
31
31
|
|
|
32
|
-
|
|
33
32
|
try:
|
|
34
33
|
from pydantic import BaseModel, FailFast, TypeAdapter
|
|
35
34
|
|
|
@@ -110,6 +109,35 @@ except ImportError:
|
|
|
110
109
|
UNSET = UnsetType.UNSET # pyright: ignore[reportConstantRedefinition]
|
|
111
110
|
MSGSPEC_INSTALLED = False # pyright: ignore[reportConstantRedefinition]
|
|
112
111
|
|
|
112
|
+
try:
|
|
113
|
+
from litestar.dto.data_structures import DTOData # pyright: ignore[reportUnknownVariableType]
|
|
114
|
+
|
|
115
|
+
LITESTAR_INSTALLED = True
|
|
116
|
+
except ImportError:
|
|
117
|
+
|
|
118
|
+
@runtime_checkable
|
|
119
|
+
class DTOData(Protocol[T]): # type: ignore[no-redef]
|
|
120
|
+
"""Placeholder implementation"""
|
|
121
|
+
|
|
122
|
+
__slots__ = ("_backend", "_data_as_builtins")
|
|
123
|
+
|
|
124
|
+
def __init__(self, backend: Any, data_as_builtins: Any) -> None:
|
|
125
|
+
"""Placeholder init"""
|
|
126
|
+
|
|
127
|
+
def create_instance(self, **kwargs: Any) -> T:
|
|
128
|
+
"""Placeholder implementation"""
|
|
129
|
+
return cast("T", kwargs)
|
|
130
|
+
|
|
131
|
+
def update_instance(self, instance: T, **kwargs: Any) -> T:
|
|
132
|
+
"""Placeholder implementation"""
|
|
133
|
+
return cast("T", kwargs)
|
|
134
|
+
|
|
135
|
+
def as_builtins(self) -> Any:
|
|
136
|
+
"""Placeholder implementation"""
|
|
137
|
+
return {}
|
|
138
|
+
|
|
139
|
+
LITESTAR_INSTALLED = False # pyright: ignore[reportConstantRedefinition]
|
|
140
|
+
|
|
113
141
|
|
|
114
142
|
class EmptyEnum(Enum):
|
|
115
143
|
"""A sentinel enum used as placeholder."""
|
|
@@ -122,10 +150,12 @@ Empty: Final = EmptyEnum.EMPTY
|
|
|
122
150
|
|
|
123
151
|
|
|
124
152
|
__all__ = (
|
|
153
|
+
"LITESTAR_INSTALLED",
|
|
125
154
|
"MSGSPEC_INSTALLED",
|
|
126
155
|
"PYDANTIC_INSTALLED",
|
|
127
156
|
"UNSET",
|
|
128
157
|
"BaseModel",
|
|
158
|
+
"DTOData",
|
|
129
159
|
"DataclassProtocol",
|
|
130
160
|
"Empty",
|
|
131
161
|
"EmptyEnum",
|
|
@@ -2,31 +2,31 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from contextlib import contextmanager
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from sqlspec.
|
|
7
|
+
from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
|
|
8
8
|
from sqlspec.typing import Empty, EmptyType
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from collections.abc import Generator
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
|
-
from adbc_driver_manager.dbapi import Connection
|
|
14
|
+
from adbc_driver_manager.dbapi import Connection
|
|
15
15
|
|
|
16
16
|
__all__ = ("AdbcDatabaseConfig",)
|
|
17
17
|
|
|
18
|
-
ConnectionT = TypeVar("ConnectionT", bound="Connection")
|
|
19
|
-
CursorT = TypeVar("CursorT", bound="Cursor")
|
|
20
|
-
|
|
21
18
|
|
|
22
19
|
@dataclass
|
|
23
|
-
class AdbcDatabaseConfig(GenericDatabaseConfig):
|
|
20
|
+
class AdbcDatabaseConfig(NoPoolConfig["Connection"], GenericDatabaseConfig):
|
|
24
21
|
"""Configuration for ADBC connections.
|
|
25
22
|
|
|
26
23
|
This class provides configuration options for ADBC database connections using the
|
|
27
24
|
ADBC Driver Manager.([1](https://arrow.apache.org/adbc/current/python/api/adbc_driver_manager.html))
|
|
28
25
|
"""
|
|
29
26
|
|
|
27
|
+
__supports_connection_pooling = False
|
|
28
|
+
__is_async = False
|
|
29
|
+
|
|
30
30
|
uri: str | EmptyType = Empty
|
|
31
31
|
"""Database URI"""
|
|
32
32
|
driver_name: str | EmptyType = Empty
|
|
@@ -4,7 +4,7 @@ from contextlib import asynccontextmanager
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
|
-
from sqlspec.
|
|
7
|
+
from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
|
|
8
8
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
9
9
|
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ __all__ = ("AiosqliteConfig",)
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
@dataclass
|
|
22
|
-
class AiosqliteConfig(GenericDatabaseConfig):
|
|
22
|
+
class AiosqliteConfig(NoPoolConfig["Connection"], GenericDatabaseConfig):
|
|
23
23
|
"""Configuration for Aiosqlite database connections.
|
|
24
24
|
|
|
25
25
|
This class provides configuration options for Aiosqlite database connections, wrapping all parameters
|
|
@@ -4,6 +4,10 @@ from contextlib import asynccontextmanager
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from typing import TYPE_CHECKING, TypeVar
|
|
6
6
|
|
|
7
|
+
from asyncmy.connection import Connection
|
|
8
|
+
from asyncmy.pool import Pool
|
|
9
|
+
|
|
10
|
+
from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
|
|
7
11
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
8
12
|
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
|
|
9
13
|
|
|
@@ -11,9 +15,7 @@ if TYPE_CHECKING:
|
|
|
11
15
|
from collections.abc import AsyncGenerator
|
|
12
16
|
from typing import Any
|
|
13
17
|
|
|
14
|
-
from asyncmy.connection import Connection
|
|
15
18
|
from asyncmy.cursors import Cursor, DictCursor
|
|
16
|
-
from asyncmy.pool import Pool
|
|
17
19
|
|
|
18
20
|
__all__ = (
|
|
19
21
|
"AsyncMyConfig",
|
|
@@ -25,7 +27,7 @@ T = TypeVar("T")
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
@dataclass
|
|
28
|
-
class AsyncmyPoolConfig:
|
|
30
|
+
class AsyncmyPoolConfig(GenericPoolConfig):
|
|
29
31
|
"""Configuration for Asyncmy's connection pool.
|
|
30
32
|
|
|
31
33
|
This class provides configuration options for Asyncmy database connection pools.
|
|
@@ -104,9 +106,12 @@ class AsyncmyPoolConfig:
|
|
|
104
106
|
|
|
105
107
|
|
|
106
108
|
@dataclass
|
|
107
|
-
class AsyncMyConfig:
|
|
109
|
+
class AsyncMyConfig(DatabaseConfigProtocol[Connection, Pool], GenericDatabaseConfig):
|
|
108
110
|
"""Asyncmy Configuration."""
|
|
109
111
|
|
|
112
|
+
__is_async__ = True
|
|
113
|
+
__supports_connection_pooling__ = True
|
|
114
|
+
|
|
110
115
|
pool_config: AsyncmyPoolConfig | None = None
|
|
111
116
|
"""Asyncmy Pool configuration"""
|
|
112
117
|
|
|
@@ -2,13 +2,16 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from contextlib import asynccontextmanager
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING, TypeVar
|
|
5
|
+
from typing import TYPE_CHECKING, TypeVar, Union
|
|
6
6
|
|
|
7
7
|
from asyncpg import Record
|
|
8
8
|
from asyncpg import create_pool as asyncpg_create_pool
|
|
9
|
+
from asyncpg.connection import Connection
|
|
10
|
+
from asyncpg.pool import Pool, PoolConnectionProxy
|
|
11
|
+
from typing_extensions import TypeAlias
|
|
9
12
|
|
|
10
13
|
from sqlspec._serialization import decode_json, encode_json
|
|
11
|
-
from sqlspec.
|
|
14
|
+
from sqlspec.base import DatabaseConfigProtocol, GenericDatabaseConfig, GenericPoolConfig
|
|
12
15
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
13
16
|
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
|
|
14
17
|
|
|
@@ -17,8 +20,6 @@ if TYPE_CHECKING:
|
|
|
17
20
|
from collections.abc import AsyncGenerator, Awaitable, Callable, Coroutine
|
|
18
21
|
from typing import Any
|
|
19
22
|
|
|
20
|
-
from asyncpg.connection import Connection
|
|
21
|
-
from asyncpg.pool import Pool, PoolConnectionProxy
|
|
22
23
|
|
|
23
24
|
__all__ = (
|
|
24
25
|
"AsyncPgConfig",
|
|
@@ -28,6 +29,8 @@ __all__ = (
|
|
|
28
29
|
|
|
29
30
|
T = TypeVar("T")
|
|
30
31
|
|
|
32
|
+
PgConnection: TypeAlias = Union[Connection, PoolConnectionProxy]
|
|
33
|
+
|
|
31
34
|
|
|
32
35
|
@dataclass
|
|
33
36
|
class AsyncPgPoolConfig(GenericPoolConfig):
|
|
@@ -70,9 +73,12 @@ class AsyncPgPoolConfig(GenericPoolConfig):
|
|
|
70
73
|
|
|
71
74
|
|
|
72
75
|
@dataclass
|
|
73
|
-
class AsyncPgConfig(GenericDatabaseConfig):
|
|
76
|
+
class AsyncPgConfig(DatabaseConfigProtocol[PgConnection, Pool], GenericDatabaseConfig):
|
|
74
77
|
"""Asyncpg Configuration."""
|
|
75
78
|
|
|
79
|
+
__is_async__ = True
|
|
80
|
+
__supports_connection_pooling__ = True
|
|
81
|
+
|
|
76
82
|
pool_config: AsyncPgPoolConfig | None = None
|
|
77
83
|
"""Asyncpg Pool configuration"""
|
|
78
84
|
json_deserializer: Callable[[str], Any] = decode_json
|
|
@@ -132,9 +138,7 @@ class AsyncPgConfig(GenericDatabaseConfig):
|
|
|
132
138
|
return self.create_pool()
|
|
133
139
|
|
|
134
140
|
@asynccontextmanager
|
|
135
|
-
async def provide_connection(
|
|
136
|
-
self, *args: Any, **kwargs: Any
|
|
137
|
-
) -> AsyncGenerator[Connection | PoolConnectionProxy, None]:
|
|
141
|
+
async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[PoolConnectionProxy, None]:
|
|
138
142
|
"""Create a connection instance.
|
|
139
143
|
|
|
140
144
|
Returns:
|
|
@@ -4,14 +4,15 @@ from contextlib import contextmanager
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from typing import TYPE_CHECKING, Any, cast
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from duckdb import DuckDBPyConnection
|
|
8
|
+
|
|
9
|
+
from sqlspec.base import GenericDatabaseConfig, NoPoolConfig
|
|
8
10
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
9
11
|
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
|
|
10
12
|
|
|
11
13
|
if TYPE_CHECKING:
|
|
12
14
|
from collections.abc import Generator, Sequence
|
|
13
15
|
|
|
14
|
-
from duckdb import DuckDBPyConnection
|
|
15
16
|
|
|
16
17
|
__all__ = ("DuckDBConfig", "ExtensionConfig")
|
|
17
18
|
|
|
@@ -23,21 +24,21 @@ class ExtensionConfig:
|
|
|
23
24
|
This class provides configuration options for DuckDB extensions, including installation
|
|
24
25
|
and post-install configuration settings.
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
name: The name of the extension to install
|
|
28
|
-
config: Optional configuration settings to apply after installation
|
|
29
|
-
force_install: Whether to force reinstall if already present
|
|
30
|
-
repository: Optional repository name to install from
|
|
31
|
-
repository_url: Optional repository URL to install from
|
|
32
|
-
version: Optional version of the extension to install
|
|
27
|
+
For details see: https://duckdb.org/docs/extensions/overview
|
|
33
28
|
"""
|
|
34
29
|
|
|
35
30
|
name: str
|
|
31
|
+
"""The name of the extension to install"""
|
|
36
32
|
config: dict[str, Any] | None = None
|
|
33
|
+
"""Optional configuration settings to apply after installation"""
|
|
37
34
|
force_install: bool = False
|
|
35
|
+
"""Whether to force reinstall if already present"""
|
|
38
36
|
repository: str | None = None
|
|
37
|
+
"""Optional repository name to install from"""
|
|
39
38
|
repository_url: str | None = None
|
|
39
|
+
"""Optional repository URL to install from"""
|
|
40
40
|
version: str | None = None
|
|
41
|
+
"""Optional version of the extension to install"""
|
|
41
42
|
|
|
42
43
|
@classmethod
|
|
43
44
|
def from_dict(cls, name: str, config: dict[str, Any] | bool | None = None) -> ExtensionConfig:
|
|
@@ -65,7 +66,7 @@ class ExtensionConfig:
|
|
|
65
66
|
|
|
66
67
|
|
|
67
68
|
@dataclass
|
|
68
|
-
class DuckDBConfig(GenericDatabaseConfig):
|
|
69
|
+
class DuckDBConfig(NoPoolConfig[DuckDBPyConnection], GenericDatabaseConfig):
|
|
69
70
|
"""Configuration for DuckDB database connections.
|
|
70
71
|
|
|
71
72
|
This class provides configuration options for DuckDB database connections, wrapping all parameters
|
|
@@ -114,13 +115,13 @@ class DuckDBConfig(GenericDatabaseConfig):
|
|
|
114
115
|
msg = "When configuring extensions in the 'config' dictionary, the value must be a dictionary or sequence of extension names"
|
|
115
116
|
raise ImproperConfigurationError(msg)
|
|
116
117
|
if not isinstance(_e, dict):
|
|
117
|
-
_e = {str(ext): {"force_install": False} for ext in _e}
|
|
118
|
+
_e = {str(ext): {"force_install": False} for ext in _e} # pyright: ignore[reportUnknownVariableType,reportUnknownArgumentType]
|
|
118
119
|
|
|
119
|
-
if len(set(_e.keys()).intersection({ext.name for ext in self.extensions})) > 0:
|
|
120
|
+
if len(set(_e.keys()).intersection({ext.name for ext in self.extensions})) > 0: # pyright: ignore[ reportUnknownArgumentType]
|
|
120
121
|
msg = "Configuring the same extension in both 'extensions' and as a key in 'config['extensions']' is not allowed"
|
|
121
122
|
raise ImproperConfigurationError(msg)
|
|
122
123
|
|
|
123
|
-
self.extensions.extend([ExtensionConfig.from_dict(name, ext_config) for name, ext_config in _e.items()])
|
|
124
|
+
self.extensions.extend([ExtensionConfig.from_dict(name, ext_config) for name, ext_config in _e.items()]) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
|
|
124
125
|
|
|
125
126
|
def _configure_extensions(self, connection: DuckDBPyConnection) -> None:
|
|
126
127
|
"""Configure extensions for the connection.
|
|
@@ -177,7 +178,7 @@ class DuckDBConfig(GenericDatabaseConfig):
|
|
|
177
178
|
import duckdb
|
|
178
179
|
|
|
179
180
|
try:
|
|
180
|
-
connection = duckdb.connect(**self.connection_config_dict)
|
|
181
|
+
connection = duckdb.connect(**self.connection_config_dict) # pyright: ignore[reportUnknownMemberType]
|
|
181
182
|
self._configure_extensions(connection)
|
|
182
183
|
return connection
|
|
183
184
|
except Exception as e:
|
|
@@ -26,14 +26,17 @@ __all__ = (
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
@dataclass
|
|
29
|
-
class OracleAsyncPoolConfig(OracleGenericPoolConfig[
|
|
29
|
+
class OracleAsyncPoolConfig(OracleGenericPoolConfig[AsyncConnection, AsyncConnectionPool]):
|
|
30
30
|
"""Async Oracle Pool Config"""
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
@dataclass
|
|
34
|
-
class OracleAsyncDatabaseConfig(OracleGenericDatabaseConfig[
|
|
34
|
+
class OracleAsyncDatabaseConfig(OracleGenericDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
|
|
35
35
|
"""Async Oracle database Configuration."""
|
|
36
36
|
|
|
37
|
+
__is_async__ = True
|
|
38
|
+
__supports_connection_pooling__ = True
|
|
39
|
+
|
|
37
40
|
pool_config: OracleAsyncPoolConfig | None = None
|
|
38
41
|
"""Oracle Pool configuration"""
|
|
39
42
|
pool_instance: AsyncConnectionPool | None = None
|
|
@@ -70,7 +73,7 @@ class OracleAsyncDatabaseConfig(OracleGenericDatabaseConfig[AsyncConnectionPool,
|
|
|
70
73
|
|
|
71
74
|
pool_config = self.pool_config_dict
|
|
72
75
|
self.pool_instance = oracledb_create_pool(**pool_config)
|
|
73
|
-
if self.pool_instance is None:
|
|
76
|
+
if self.pool_instance is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
74
77
|
msg = "Could not configure the 'pool_instance'. Please check your configuration."
|
|
75
78
|
raise ImproperConfigurationError(msg)
|
|
76
79
|
return self.pool_instance
|