sqlspec 0.4.0__py3-none-any.whl → 0.6.0__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.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (36) hide show
  1. sqlspec/__metadata__.py +1 -1
  2. sqlspec/_serialization.py +1 -1
  3. sqlspec/_typing.py +31 -1
  4. sqlspec/adapters/adbc/config.py +7 -7
  5. sqlspec/adapters/aiosqlite/config.py +11 -18
  6. sqlspec/adapters/asyncmy/config.py +9 -4
  7. sqlspec/adapters/asyncpg/config.py +10 -10
  8. sqlspec/adapters/duckdb/__init__.py +3 -0
  9. sqlspec/adapters/duckdb/config.py +15 -14
  10. sqlspec/adapters/oracledb/__init__.py +1 -1
  11. sqlspec/adapters/oracledb/config/_asyncio.py +17 -7
  12. sqlspec/adapters/oracledb/config/_common.py +7 -25
  13. sqlspec/adapters/oracledb/config/_sync.py +17 -7
  14. sqlspec/adapters/psycopg/config/__init__.py +2 -2
  15. sqlspec/adapters/psycopg/config/_async.py +13 -8
  16. sqlspec/adapters/psycopg/config/_common.py +3 -18
  17. sqlspec/adapters/psycopg/config/_sync.py +12 -8
  18. sqlspec/adapters/sqlite/config.py +3 -3
  19. sqlspec/base.py +221 -0
  20. sqlspec/extensions/litestar/config.py +0 -0
  21. sqlspec/extensions/litestar/plugin.py +18 -10
  22. sqlspec/filters.py +2 -1
  23. sqlspec/typing.py +119 -31
  24. sqlspec/utils/__init__.py +0 -0
  25. sqlspec/utils/deprecation.py +111 -0
  26. sqlspec/utils/fixtures.py +66 -0
  27. sqlspec/utils/module_loader.py +94 -0
  28. sqlspec/utils/text.py +46 -0
  29. sqlspec-0.6.0.dist-info/METADATA +128 -0
  30. sqlspec-0.6.0.dist-info/RECORD +46 -0
  31. sqlspec-0.6.0.dist-info/licenses/LICENSE +21 -0
  32. sqlspec/config.py +0 -16
  33. sqlspec-0.4.0.dist-info/METADATA +0 -84
  34. sqlspec-0.4.0.dist-info/RECORD +0 -39
  35. {sqlspec-0.4.0.dist-info → sqlspec-0.6.0.dist-info}/WHEEL +0 -0
  36. {sqlspec-0.4.0.dist-info → sqlspec-0.6.0.dist-info}/licenses/NOTICE +0 -0
@@ -0,0 +1,111 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ from functools import wraps
5
+ from typing import Callable, Literal
6
+ from warnings import warn
7
+
8
+ from typing_extensions import ParamSpec, TypeVar
9
+
10
+ __all__ = ("deprecated", "warn_deprecation")
11
+
12
+
13
+ T = TypeVar("T")
14
+ P = ParamSpec("P")
15
+ DeprecatedKind = Literal["function", "method", "classmethod", "attribute", "property", "class", "parameter", "import"]
16
+
17
+
18
+ def warn_deprecation(
19
+ version: str,
20
+ deprecated_name: str,
21
+ kind: DeprecatedKind,
22
+ *,
23
+ removal_in: str | None = None,
24
+ alternative: str | None = None,
25
+ info: str | None = None,
26
+ pending: bool = False,
27
+ ) -> None:
28
+ """Warn about a call to a (soon to be) deprecated function.
29
+
30
+ Args:
31
+ version: Advanced Alchemy version where the deprecation will occur
32
+ deprecated_name: Name of the deprecated function
33
+ removal_in: Advanced Alchemy version where the deprecated function will be removed
34
+ alternative: Name of a function that should be used instead
35
+ info: Additional information
36
+ pending: Use :class:`warnings.PendingDeprecationWarning` instead of :class:`warnings.DeprecationWarning`
37
+ kind: Type of the deprecated thing
38
+ """
39
+ parts = []
40
+
41
+ if kind == "import":
42
+ access_type = "Import of"
43
+ elif kind in {"function", "method"}:
44
+ access_type = "Call to"
45
+ else:
46
+ access_type = "Use of"
47
+
48
+ if pending:
49
+ parts.append(f"{access_type} {kind} awaiting deprecation {deprecated_name!r}") # pyright: ignore[reportUnknownMemberType]
50
+ else:
51
+ parts.append(f"{access_type} deprecated {kind} {deprecated_name!r}") # pyright: ignore[reportUnknownMemberType]
52
+
53
+ parts.extend( # pyright: ignore[reportUnknownMemberType]
54
+ (
55
+ f"Deprecated in advanced-alchemy {version}",
56
+ f"This {kind} will be removed in {removal_in or 'the next major version'}",
57
+ ),
58
+ )
59
+ if alternative:
60
+ parts.append(f"Use {alternative!r} instead") # pyright: ignore[reportUnknownMemberType]
61
+
62
+ if info:
63
+ parts.append(info) # pyright: ignore[reportUnknownMemberType]
64
+
65
+ text = ". ".join(parts) # pyright: ignore[reportUnknownArgumentType]
66
+ warning_class = PendingDeprecationWarning if pending else DeprecationWarning
67
+
68
+ warn(text, warning_class, stacklevel=2)
69
+
70
+
71
+ def deprecated(
72
+ version: str,
73
+ *,
74
+ removal_in: str | None = None,
75
+ alternative: str | None = None,
76
+ info: str | None = None,
77
+ pending: bool = False,
78
+ kind: Literal["function", "method", "classmethod", "property"] | None = None,
79
+ ) -> Callable[[Callable[P, T]], Callable[P, T]]:
80
+ """Create a decorator wrapping a function, method or property with a warning call about a (pending) deprecation.
81
+
82
+ Args:
83
+ version: Litestar version where the deprecation will occur
84
+ removal_in: Litestar version where the deprecated function will be removed
85
+ alternative: Name of a function that should be used instead
86
+ info: Additional information
87
+ pending: Use :class:`warnings.PendingDeprecationWarning` instead of :class:`warnings.DeprecationWarning`
88
+ kind: Type of the deprecated callable. If ``None``, will use ``inspect`` to figure
89
+ out if it's a function or method
90
+
91
+ Returns:
92
+ A decorator wrapping the function call with a warning
93
+ """
94
+
95
+ def decorator(func: Callable[P, T]) -> Callable[P, T]:
96
+ @wraps(func)
97
+ def wrapped(*args: P.args, **kwargs: P.kwargs) -> T:
98
+ warn_deprecation(
99
+ version=version,
100
+ deprecated_name=func.__name__,
101
+ info=info,
102
+ alternative=alternative,
103
+ pending=pending,
104
+ removal_in=removal_in,
105
+ kind=kind or ("method" if inspect.ismethod(func) else "function"),
106
+ )
107
+ return func(*args, **kwargs)
108
+
109
+ return wrapped
110
+
111
+ return decorator
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from sqlspec._serialization import decode_json
6
+ from sqlspec.exceptions import MissingDependencyError
7
+
8
+ if TYPE_CHECKING:
9
+ from pathlib import Path
10
+
11
+ from anyio import Path as AsyncPath
12
+
13
+ __all__ = ("open_fixture", "open_fixture_async")
14
+
15
+
16
+ def open_fixture(fixtures_path: Path | AsyncPath, fixture_name: str) -> Any:
17
+ """Loads JSON file with the specified fixture name
18
+
19
+ Args:
20
+ fixtures_path: :class:`pathlib.Path` | :class:`anyio.Path` The path to look for fixtures
21
+ fixture_name (str): The fixture name to load.
22
+
23
+ Raises:
24
+ :class:`FileNotFoundError`: Fixtures not found.
25
+
26
+ Returns:
27
+ Any: The parsed JSON data
28
+ """
29
+ from pathlib import Path
30
+
31
+ fixture = Path(fixtures_path / f"{fixture_name}.json")
32
+ if fixture.exists():
33
+ with fixture.open(mode="r", encoding="utf-8") as f:
34
+ f_data = f.read()
35
+ return decode_json(f_data)
36
+ msg = f"Could not find the {fixture_name} fixture"
37
+ raise FileNotFoundError(msg)
38
+
39
+
40
+ async def open_fixture_async(fixtures_path: Path | AsyncPath, fixture_name: str) -> Any:
41
+ """Loads JSON file with the specified fixture name
42
+
43
+ Args:
44
+ fixtures_path: :class:`pathlib.Path` | :class:`anyio.Path` The path to look for fixtures
45
+ fixture_name (str): The fixture name to load.
46
+
47
+ Raises:
48
+ :class:`~advanced_alchemy.exceptions.MissingDependencyError`: The `anyio` library is required to use this function.
49
+ :class:`FileNotFoundError`: Fixtures not found.
50
+
51
+ Returns:
52
+ Any: The parsed JSON data
53
+ """
54
+ try:
55
+ from anyio import Path as AsyncPath
56
+ except ImportError as exc:
57
+ msg = "The `anyio` library is required to use this function. Please install it with `pip install anyio`."
58
+ raise MissingDependencyError(msg) from exc
59
+
60
+ fixture = AsyncPath(fixtures_path / f"{fixture_name}.json")
61
+ if await fixture.exists():
62
+ async with await fixture.open(mode="r", encoding="utf-8") as f:
63
+ f_data = await f.read()
64
+ return decode_json(f_data)
65
+ msg = f"Could not find the {fixture_name} fixture"
66
+ raise FileNotFoundError(msg)
@@ -0,0 +1,94 @@
1
+ """General utility functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from importlib import import_module
7
+ from importlib.util import find_spec
8
+ from pathlib import Path
9
+ from typing import TYPE_CHECKING, Any
10
+
11
+ if TYPE_CHECKING:
12
+ from types import ModuleType
13
+
14
+ __all__ = (
15
+ "import_string",
16
+ "module_to_os_path",
17
+ )
18
+
19
+
20
+ def module_to_os_path(dotted_path: str = "app") -> Path:
21
+ """Find Module to OS Path.
22
+
23
+ Return a path to the base directory of the project or the module
24
+ specified by `dotted_path`.
25
+
26
+ Args:
27
+ dotted_path: The path to the module. Defaults to "app".
28
+
29
+ Raises:
30
+ TypeError: The module could not be found.
31
+
32
+ Returns:
33
+ Path: The path to the module.
34
+ """
35
+ try:
36
+ if (src := find_spec(dotted_path)) is None: # pragma: no cover
37
+ msg = f"Couldn't find the path for {dotted_path}"
38
+ raise TypeError(msg)
39
+ except ModuleNotFoundError as e:
40
+ msg = f"Couldn't find the path for {dotted_path}"
41
+ raise TypeError(msg) from e
42
+
43
+ path = Path(str(src.origin))
44
+ return path.parent if path.is_file() else path
45
+
46
+
47
+ def import_string(dotted_path: str) -> Any:
48
+ """Dotted Path Import.
49
+
50
+ Import a dotted module path and return the attribute/class designated by the
51
+ last name in the path. Raise ImportError if the import failed.
52
+
53
+ Args:
54
+ dotted_path: The path of the module to import.
55
+
56
+ Raises:
57
+ ImportError: Could not import the module.
58
+
59
+ Returns:
60
+ object: The imported object.
61
+ """
62
+
63
+ def _is_loaded(module: ModuleType | None) -> bool:
64
+ spec = getattr(module, "__spec__", None)
65
+ initializing = getattr(spec, "_initializing", False)
66
+ return bool(module and spec and not initializing)
67
+
68
+ def _cached_import(module_path: str, class_name: str) -> Any:
69
+ """Import and cache a class from a module.
70
+
71
+ Args:
72
+ module_path: dotted path to module.
73
+ class_name: Class or function name.
74
+
75
+ Returns:
76
+ object: The imported class or function
77
+ """
78
+ # Check whether module is loaded and fully initialized.
79
+ module = sys.modules.get(module_path)
80
+ if not _is_loaded(module):
81
+ module = import_module(module_path)
82
+ return getattr(module, class_name)
83
+
84
+ try:
85
+ module_path, class_name = dotted_path.rsplit(".", 1)
86
+ except ValueError as e:
87
+ msg = "%s doesn't look like a module path"
88
+ raise ImportError(msg, dotted_path) from e
89
+
90
+ try:
91
+ return _cached_import(module_path, class_name)
92
+ except AttributeError as e:
93
+ msg = "Module '%s' does not define a '%s' attribute/class"
94
+ raise ImportError(msg, module_path, class_name) from e
sqlspec/utils/text.py ADDED
@@ -0,0 +1,46 @@
1
+ """General utility functions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ import unicodedata
7
+
8
+ __all__ = (
9
+ "check_email",
10
+ "slugify",
11
+ )
12
+
13
+
14
+ def check_email(email: str) -> str:
15
+ """Validate an email."""
16
+ if "@" not in email:
17
+ msg = "Invalid email!"
18
+ raise ValueError(msg)
19
+ return email.lower()
20
+
21
+
22
+ def slugify(value: str, allow_unicode: bool = False, separator: str | None = None) -> str:
23
+ """Slugify.
24
+
25
+ Convert to ASCII if ``allow_unicode`` is ``False``. Convert spaces or repeated
26
+ dashes to single dashes. Remove characters that aren't alphanumerics,
27
+ underscores, or hyphens. Convert to lowercase. Also strip leading and
28
+ trailing whitespace, dashes, and underscores.
29
+
30
+ Args:
31
+ value (str): the string to slugify
32
+ allow_unicode (bool, optional): allow unicode characters in slug. Defaults to False.
33
+ separator (str, optional): by default a `-` is used to delimit word boundaries.
34
+ Set this to configure something different.
35
+
36
+ Returns:
37
+ str: a slugified string of the value parameter
38
+ """
39
+ if allow_unicode:
40
+ value = unicodedata.normalize("NFKC", value)
41
+ else:
42
+ value = unicodedata.normalize("NFKD", value).encode("ascii", "ignore").decode("ascii")
43
+ value = re.sub(r"[^\w\s-]", "", value.lower())
44
+ if separator is not None:
45
+ return re.sub(r"[-\s]+", "-", value).strip("-_").replace("-", separator)
46
+ return re.sub(r"[-\s]+", "-", value).strip("-_")
@@ -0,0 +1,128 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqlspec
3
+ Version: 0.6.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-Expression: MIT
8
+ License-File: LICENSE
9
+ License-File: NOTICE
10
+ Requires-Python: <4.0,>=3.9
11
+ Requires-Dist: eval-type-backport; python_version < '3.10'
12
+ Requires-Dist: sqlglot
13
+ Requires-Dist: typing-extensions
14
+ Provides-Extra: adbc
15
+ Requires-Dist: adbc-driver-manager; extra == 'adbc'
16
+ Requires-Dist: pyarrow; extra == 'adbc'
17
+ Provides-Extra: aioodbc
18
+ Requires-Dist: aioodbc; extra == 'aioodbc'
19
+ Provides-Extra: aiosqlite
20
+ Requires-Dist: aiosqlite; extra == 'aiosqlite'
21
+ Provides-Extra: asyncmy
22
+ Requires-Dist: asyncmy; extra == 'asyncmy'
23
+ Provides-Extra: asyncpg
24
+ Requires-Dist: asyncpg; extra == 'asyncpg'
25
+ Provides-Extra: bigquery
26
+ Requires-Dist: google-cloud-bigquery; extra == 'bigquery'
27
+ Provides-Extra: duckdb
28
+ Requires-Dist: duckdb; extra == 'duckdb'
29
+ Provides-Extra: fastapi
30
+ Requires-Dist: fastapi; extra == 'fastapi'
31
+ Provides-Extra: flask
32
+ Requires-Dist: flask; extra == 'flask'
33
+ Provides-Extra: litestar
34
+ Requires-Dist: litestar; extra == 'litestar'
35
+ Provides-Extra: msgspec
36
+ Requires-Dist: msgspec; extra == 'msgspec'
37
+ Provides-Extra: oracledb
38
+ Requires-Dist: oracledb; extra == 'oracledb'
39
+ Provides-Extra: performance
40
+ Requires-Dist: sqlglot[rs]; extra == 'performance'
41
+ Provides-Extra: psycopg
42
+ Requires-Dist: psycopg[binary,pool]; extra == 'psycopg'
43
+ Provides-Extra: pydantic
44
+ Requires-Dist: pydantic; extra == 'pydantic'
45
+ Provides-Extra: pymssql
46
+ Requires-Dist: pymssql; extra == 'pymssql'
47
+ Provides-Extra: pymysql
48
+ Requires-Dist: pymysql; extra == 'pymysql'
49
+ Provides-Extra: spanner
50
+ Requires-Dist: google-cloud-spanner; extra == 'spanner'
51
+ Description-Content-Type: text/markdown
52
+
53
+ # SQLSpec
54
+
55
+ ## A Query Mapper for Python
56
+
57
+ 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.
58
+
59
+ **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!
60
+
61
+ ## Core Features (Planned but subject to change, removal or redesign)
62
+
63
+ - **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.
64
+ - **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.
65
+ - **Type-Safe Queries**: Quickly map SQL queries to typed objects using libraries such as Pydantic, Msgspec, Attrs, etc.
66
+ - **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.
67
+ - **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!)
68
+ - **Dynamic Query Manipulation**: Easily apply filters to pre-defined queries with a fluent, Pythonic API. Safely manipulate queries without the risk of SQL injection.
69
+ - **Dialect Validation and Conversion**: Use `sqlglot` to validate your SQL against specific dialects and seamlessly convert between them.
70
+ - **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.
71
+ - **Basic Migration Management**: A mechanism to generate empty migration files where you can add your own SQL and intelligently track which migrations have been applied.
72
+
73
+ ## What SQLSpec Is Not (Yet)
74
+
75
+ 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.
76
+
77
+ ## Inspiration and Future Direction
78
+
79
+ 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.
80
+
81
+ ## Current Focus: Universal Connectivity
82
+
83
+ 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.
84
+
85
+ ## Adapters: Completed, In Progress, and Planned
86
+
87
+ This list is not final. If you have a driver you'd like to see added, please open an issue or submit a PR!
88
+
89
+ | Driver | Database | Mode | Status |
90
+ | :----------------------------------------------------------------------------------------------------------- | :--------- | :------ | :--------- |
91
+ | [`adbc`](https://arrow.apache.org/adbc/) | Postgres | Sync | ✅ |
92
+ | [`adbc`](https://arrow.apache.org/adbc/) | SQLite | Sync | ✅ |
93
+ | [`adbc`](https://arrow.apache.org/adbc/) | Snowflake | Sync | ✅ |
94
+ | [`adbc`](https://arrow.apache.org/adbc/) | DuckDB | Sync | ✅ |
95
+ | [`asyncpg`](https://magicstack.github.io/asyncpg/current/) | PostgreSQL | Async | ✅ |
96
+ | [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Sync | ✅ |
97
+ | [`psycopg`](https://www.psycopg.org/) | PostgreSQL | Async | ✅ |
98
+ | [`aiosqlite`](https://github.com/omnilib/aiosqlite) | SQLite | Async | ✅ |
99
+ | `sqlite3` | SQLite | Sync | ✅ |
100
+ | [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Async | ✅ |
101
+ | [`oracledb`](https://oracle.github.io/python-oracledb/) | Oracle | Sync | ✅ |
102
+ | [`duckdb`](https://duckdb.org/) | DuckDB | Sync | ✅ |
103
+ | [`bigquery`](https://googleapis.dev/python/bigquery/latest/index.html) | BigQuery | Sync | 🗓️ |
104
+ | [`spanner`](https://googleapis.dev/python/spanner/latest/index.html) | Spanner | Sync | 🗓️ |
105
+ | [`sqlserver`](https://docs.microsoft.com/en-us/sql/connect/python/pyodbc/python-sql-driver-for-pyodbc?view=sql-server-ver16) | SQL Server | Sync | 🗓️ |
106
+ | [`mysql`](https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-python.html) | MySQL | Sync | 🗓️ |
107
+ | [`snowflake`](https://docs.snowflake.com) | Snowflake | Sync | 🗓️ |
108
+
109
+ ## Proposed Project Structure
110
+
111
+ - `sqlspec/`:
112
+ - `adapters/`: Contains all database drivers and associated configuration.
113
+ - `extensions/`:
114
+ - `litestar/`: Future home of `litestar` integration.
115
+ - `fastapi/`: Future home of `fastapi` integration.
116
+ - `flask/`: Future home of `flask` integration.
117
+ - `*/`: Future home of your favorite framework integration 🔌 ✨
118
+ - `base.py`: Contains base protocols for database configurations.
119
+ - `filters.py`: Contains the `Filter` class which is used to apply filters to pre-defined SQL queries.
120
+ - `utils/`: Contains utility functions used throughout the project.
121
+ - `exceptions.py`: Contains custom exceptions for SQLSpec.
122
+ - `typing.py`: Contains type hints, type guards and several facades for optional libraries that are not required for the core functionality of SQLSpec.
123
+
124
+ ## Get Involved
125
+
126
+ 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.
127
+
128
+ **Disclaimer**: SQLSpec is under active development. Expect changes and improvements as the project evolves.
@@ -0,0 +1,46 @@
1
+ sqlspec/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
2
+ sqlspec/__metadata__.py,sha256=KWtGqYzOJaPcKEiZAsQwwnwz3cHls7wkgmdx61W01vw,496
3
+ sqlspec/_serialization.py,sha256=NnJajyQU2I1QCwE0eOBcUbG1E25aiNLOPqMk6S-52Sg,850
4
+ sqlspec/_typing.py,sha256=pJkUkgy3zra1SFV96F4PTWStWyRNV44rrZEyrtQfgbw,4235
5
+ sqlspec/base.py,sha256=b3i6biSBLovRW8ts2L1gtVQgxXHCw6S1sKjFfmj2gfQ,7713
6
+ sqlspec/exceptions.py,sha256=fhCOILBj0J7HJP67BNSC0d9YUbW8QpZPXM55xJJzE8A,3039
7
+ sqlspec/filters.py,sha256=K6AVBo1OTLVXZZiLuM7n_44MQKUT0DzZe9roiAsTX-4,3614
8
+ sqlspec/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ sqlspec/typing.py,sha256=6g8lkdYRAFWW_4Vct9D2QNOaw0AYyHHMXT7jbdT6aeI,13665
10
+ sqlspec/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ sqlspec/adapters/adbc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ sqlspec/adapters/adbc/config.py,sha256=AF5rWTqc7GHmajcCeDXyWci8ForWpQzogQbMphaHEEs,1652
13
+ sqlspec/adapters/aiosqlite/__init__.py,sha256=PLqWg24l3TooJvqA0Xf1WErrxtqwo8DEoL_Zp2iSCzs,68
14
+ sqlspec/adapters/aiosqlite/config.py,sha256=S_NU925KisY8AQAEpdTvdQI0nEOiY8Xi-CCPzsdUb7g,3956
15
+ sqlspec/adapters/asyncmy/__init__.py,sha256=o0R_Azae3FHiSZ1TQ5ZjyCneDOuvnEeMjmSkhuiKoWo,103
16
+ sqlspec/adapters/asyncmy/config.py,sha256=PUVUmi62MELljUwpZh9TYRGbmBujXkvNVgxEnvWHecA,5644
17
+ sqlspec/adapters/asyncpg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ sqlspec/adapters/asyncpg/config.py,sha256=77RIUNxGQSEED6Fg_kdP1OlpLLIkzNw9Y_pMp2eJbGg,6131
19
+ sqlspec/adapters/duckdb/__init__.py,sha256=-IC44IEsRPbz16HpQFAGkV7Bfbow8CGMruBsdMEIEf4,85
20
+ sqlspec/adapters/duckdb/config.py,sha256=rJ3nC514LVk5cUVvAP8aS0oQXot76DqwEAtGLlPm0so,8168
21
+ sqlspec/adapters/oracledb/__init__.py,sha256=f7P24wnDhDoEwgO0pJbutqqN2L0WUZWqVJIAcvphb4M,300
22
+ sqlspec/adapters/oracledb/config/__init__.py,sha256=XoHgInT4IbXjDg5ax3ncuUoVvnYB5qQjI-Ib7gwSycU,338
23
+ sqlspec/adapters/oracledb/config/_asyncio.py,sha256=yq05yLzJyMTc-9DqpRJoHu8V9T0U6MYMnt0x23ndJHY,4019
24
+ sqlspec/adapters/oracledb/config/_common.py,sha256=9FQAynMkh8ATBoVhloPqf6AMc-XSKg29N-RtzFokyhs,5334
25
+ sqlspec/adapters/oracledb/config/_sync.py,sha256=9WRAgFUOycFCtqqO8HuB8ADfv4ou1u_h01gou9dOEhI,3882
26
+ sqlspec/adapters/psycopg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ sqlspec/adapters/psycopg/config/__init__.py,sha256=y4s9ezhFu764yQIqm_qlE_HYJiumTRN_dDfewwRGSkI,342
28
+ sqlspec/adapters/psycopg/config/_async.py,sha256=r-RQeVUgIqWPNxoTegXNfS3hnFoUt2eB8JCvm5A_hEQ,3198
29
+ sqlspec/adapters/psycopg/config/_common.py,sha256=UP0BXPSEsbY-CLxLktx4vhmEO-jdSQI1eXqSeo0vjAE,2102
30
+ sqlspec/adapters/psycopg/config/_sync.py,sha256=btaJkyPj8SX_ZN5_9bu7flcqWv1_YNk4p_JauiYDriQ,3073
31
+ sqlspec/adapters/sqlite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ sqlspec/adapters/sqlite/config.py,sha256=dvxXMsUc6AgnjZyAcQ2clZM4y3iNViMUJLH2DxL-AOs,3712
33
+ sqlspec/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ sqlspec/extensions/litestar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
+ sqlspec/extensions/litestar/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ sqlspec/extensions/litestar/plugin.py,sha256=phX5x9JTIHxfC-U7-Gowq6HQilD-j13WnK2n7-93MWw,1030
37
+ sqlspec/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ sqlspec/utils/deprecation.py,sha256=MbmIs1Qz1ZIITW7TrCE-wa1nmO0x4nGqtM1AShmKYT8,3900
39
+ sqlspec/utils/fixtures.py,sha256=FbySeVuU0E_B885ulQh_J5CO_5eL51beH9X0y9zjsYU,2196
40
+ sqlspec/utils/module_loader.py,sha256=Qe52uUgAwHSMJC2aKQwMs0F1XSbwJARF-8QdASItH_M,2720
41
+ sqlspec/utils/text.py,sha256=FnlNj7drS6JwcFc3dd7BPUBP6JDSmxTZmxnZPAB-Yq0,1479
42
+ sqlspec-0.6.0.dist-info/METADATA,sha256=Tk8P_oOaDt2ujjEx0UTB_vH0v5optk4m4inl36wh5oA,9135
43
+ sqlspec-0.6.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
44
+ sqlspec-0.6.0.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
45
+ sqlspec-0.6.0.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
46
+ sqlspec-0.6.0.dist-info/RECORD,,
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Litestar Organization
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
sqlspec/config.py DELETED
@@ -1,16 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- __all__ = (
4
- "GenericDatabaseConfig",
5
- "GenericPoolConfig",
6
- )
7
-
8
-
9
- @dataclass
10
- class GenericDatabaseConfig:
11
- """Generic Database Configuration."""
12
-
13
-
14
- @dataclass
15
- class GenericPoolConfig:
16
- """Generic Database Pool Configuration."""
@@ -1,84 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: sqlspec
3
- Version: 0.4.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.9'
10
- Requires-Dist: sqlglot
11
- Requires-Dist: typing-extensions>=4.0.0
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
- <!-- markdownlint-disable -->
53
- <p align="center">
54
- <!-- github-banner-start -->
55
- <img src="https://raw.githubusercontent.com/litestar-org/branding/main/assets/Branding%20-%20SVG%20-%20Transparent/Logo%20-%20Banner%20-%20Inline%20-%20Light.svg#gh-light-mode-only" alt="Litestar Logo - Light" width="100%" height="auto" />
56
- <img src="https://raw.githubusercontent.com/litestar-org/branding/main/assets/Branding%20-%20SVG%20-%20Transparent/Logo%20-%20Banner%20-%20Inline%20-%20Dark.svg#gh-dark-mode-only" alt="Litestar Logo - Dark" width="100%" height="auto" />
57
- <!-- github-banner-end -->
58
-
59
- </p>
60
- <div align="center">
61
- <!-- markdownlint-restore -->
62
-
63
- # SQLSpec
64
-
65
- SQL Experiments in Python
66
-
67
-
68
- ## Minimal SQL Abstractions for Python.
69
-
70
- - Modern: Typed and Extensible
71
- - Multi-database: SQLite, Postgres, DuckDB, MySQL, Oracle, SQL Server, Spanner, Big Query, and more...
72
- - Easy ability to manipulate and add filters to queries
73
- - Validate and Convert between dialects with `sqlglot`
74
- - and more...
75
-
76
- ## Can it do `X`?
77
-
78
- - Probably not currently; but, if it makes sense we can add enhancements.
79
-
80
- ## Inspiration
81
-
82
- `aiosql` is the primary influence for this library. However, I wanted to be able to use the query interface from `aiosql` a bit more flexibly.
83
-
84
- Why not add it to `aiosql`? Where it makes sense, many of these changes will likely get submitted to aiosql as a PR (`spanner` and `bigquery` drivers are likely the starting point.)
@@ -1,39 +0,0 @@
1
- sqlspec/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
2
- sqlspec/__metadata__.py,sha256=Vw99abV_UQNVH2jB0IBa9-8emyZQcXm1J9eMtLxFX2Y,496
3
- sqlspec/_serialization.py,sha256=OL4x0Rz5UjF7RgAKqhYChi5qSS_ImtaVrIlA4DhIKUE,824
4
- sqlspec/_typing.py,sha256=Za41GlNdEKAGTy66GTofOiGYROE7ccFMvxZdh_vxIFk,3278
5
- sqlspec/config.py,sha256=BOX_V_q2MOP33tK0ISpYaiQJt3zrvK4D_JIBD9FOixY,272
6
- sqlspec/exceptions.py,sha256=fhCOILBj0J7HJP67BNSC0d9YUbW8QpZPXM55xJJzE8A,3039
7
- sqlspec/filters.py,sha256=H5UAn1HKm598QqDujQHwvytKHjw4QoQ2zPpgXMcYpSU,3552
8
- sqlspec/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- sqlspec/typing.py,sha256=t5fpzxUCWkKJIpFDKmUeq77RkdmNNFqMj4azgJpRS7k,11316
10
- sqlspec/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- sqlspec/adapters/adbc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- sqlspec/adapters/adbc/config.py,sha256=BeiZdqoBQXuht0GXWleqVKL_LOFI3Ygna1XWDmb-dBw,1704
13
- sqlspec/adapters/aiosqlite/__init__.py,sha256=PLqWg24l3TooJvqA0Xf1WErrxtqwo8DEoL_Zp2iSCzs,68
14
- sqlspec/adapters/aiosqlite/config.py,sha256=5DOKaYT_lBFTimrITJwIqTHoweZ2aZlQ07kti1VJtxk,3821
15
- sqlspec/adapters/asyncmy/__init__.py,sha256=o0R_Azae3FHiSZ1TQ5ZjyCneDOuvnEeMjmSkhuiKoWo,103
16
- sqlspec/adapters/asyncmy/config.py,sha256=7VsNEokhBtBgXDj2gakdwplOYPaV3ADIwWX-o22vwNk,5461
17
- sqlspec/adapters/asyncpg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- sqlspec/adapters/asyncpg/config.py,sha256=NyVvsT2x3IIZBZF6dTaSv1w6lCPEvmUprYXyTSJ9Ixk,6014
19
- sqlspec/adapters/duckdb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- sqlspec/adapters/duckdb/config.py,sha256=BgGGkk0Y3CQboQeI1aB81_ABVGmgOL1cbk_cZKzeggQ,7927
21
- sqlspec/adapters/oracledb/__init__.py,sha256=fFQ2xOxFcgpr-ug4AVv430irnJgBRUINvt4sL3qzyBw,275
22
- sqlspec/adapters/oracledb/config/__init__.py,sha256=XoHgInT4IbXjDg5ax3ncuUoVvnYB5qQjI-Ib7gwSycU,338
23
- sqlspec/adapters/oracledb/config/_asyncio.py,sha256=Z87V7t-5blS6NkMhvFjoBgUrJtKgOrTyKSl8xy2uD_M,3211
24
- sqlspec/adapters/oracledb/config/_common.py,sha256=k8ou3aWR1En1jl5uo4fORMG3CoF-XQ96qdwULtteHLo,6173
25
- sqlspec/adapters/oracledb/config/_sync.py,sha256=guCrotTdNJajcbG5xwVCLoza7wLPQxZkQaw99s4ibNE,3071
26
- sqlspec/adapters/psycopg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- sqlspec/adapters/psycopg/config/__init__.py,sha256=pXI9Pa2VYESTchPgM3tt5kFF8tsmgq-ksZRGR6pgiUQ,280
28
- sqlspec/adapters/psycopg/config/_async.py,sha256=sNQU3dzencGgOToHZuMfxoqhR9EvRyrxdWqtPDC2gUY,2712
29
- sqlspec/adapters/psycopg/config/_common.py,sha256=gC-QQDy9DNjp0DGZAT3wu7MKW8ejHe5fuHU-318Vgr0,2757
30
- sqlspec/adapters/psycopg/config/_sync.py,sha256=lwzaeO6I-nYuC7vif-bjn2jLugPwbPjTW226_hcweqo,2590
31
- sqlspec/adapters/sqlite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- sqlspec/adapters/sqlite/config.py,sha256=rCv6XWWWi1dzpmAVnwHxg-ahmAif78yfFhA548fNaT8,3697
33
- sqlspec/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- sqlspec/extensions/litestar/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- sqlspec/extensions/litestar/plugin.py,sha256=oiBFfRffNvy_vnGptREd6JYZGB6Yd98KbtVct_VcW0A,837
36
- sqlspec-0.4.0.dist-info/METADATA,sha256=OnTkY_OG3IeqaJQBkzHjsKuQwkfmhQO4WnhXKbEoDLc,3222
37
- sqlspec-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
38
- sqlspec-0.4.0.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
39
- sqlspec-0.4.0.dist-info/RECORD,,