diff --git a/databasez/__init__.py b/databasez/__init__.py index aab2301..5d2eb2f 100644 --- a/databasez/__init__.py +++ b/databasez/__init__.py @@ -1,5 +1,5 @@ from databasez.core import Database, DatabaseURL -__version__ = "0.9.4" +__version__ = "0.9.5" __all__ = ["Database", "DatabaseURL"] diff --git a/databasez/sqlalchemy.py b/databasez/sqlalchemy.py index 25cbb74..c2cdcfe 100644 --- a/databasez/sqlalchemy.py +++ b/databasez/sqlalchemy.py @@ -260,13 +260,28 @@ def extract_options( database_url: DatabaseURL, **options: typing.Any, ) -> typing.Tuple[DatabaseURL, typing.Dict[str, typing.Any]]: + # we have our own logic + options.setdefault("pool_reset_on_return", None) + new_query_options = dict(database_url.options) + for param in ["ssl", "echo", "echo_pool"]: + if param in new_query_options: + assert param not in options + value = typing.cast(str, new_query_options.pop(param)) + options[param] = value.lower() in {"true", ""} + if "isolation_level" in new_query_options: + assert "isolation_level" not in options + options["isolation_level"] = typing.cast(str, new_query_options.pop(param)) + for param in ["pool_size", "max_overflow"]: + if param in new_query_options: + assert param not in options + options[param] = int(typing.cast(str, new_query_options.pop(param))) + if "pool_recycle" in new_query_options: + assert "pool_recycle" not in options + options["pool_recycle"] = float( + typing.cast(str, new_query_options.pop("pool_recycle")) + ) if self.default_isolation_level is not None: options.setdefault("isolation_level", self.default_isolation_level) - new_query_options = dict(database_url.options) - if "ssl" in new_query_options: - assert "ssl" not in options - ssl = typing.cast(str, new_query_options.pop("ssl")) - options["ssl"] = {"true": True, "false": False}.get(ssl.lower(), ssl.lower()) return database_url.replace(options=new_query_options), options def json_serializer(self, inp: dict) -> str: diff --git a/docs/connections-and-transactions.md b/docs/connections-and-transactions.md index 313398b..ee8300d 100644 --- a/docs/connections-and-transactions.md +++ b/docs/connections-and-transactions.md @@ -108,8 +108,8 @@ and for configuring the connection pool. # Use an SSL connection. database = Database('postgresql+asyncpg://localhost/example?ssl=true') -# Use a connection pool of between 5-20 connections. -database = Database('mysql+aiomysql://localhost/example?min_size=5&max_size=20') +# Use an SSL connection and configure pool +database = Database('postgresql+asyncpg://localhost/example?ssl=true&pool_size=20') ``` You can also use keyword arguments to pass in any connection options. @@ -117,9 +117,23 @@ Available keyword arguments may differ between database backends. Keywords can b This means also the keyword extraction works like in sqlalchemy ```python -database = Database('postgresql+asyncpg://localhost/example', ssl=True, min_size=5, max_size=20) +database = Database('postgresql+asyncpg://localhost/example', ssl=True, pool_size=20) ``` +Note: not all query values are morphed into kwargs arguments. +Options which will be transformed are in `databasez/sqlalchemy.py` in `extract_options` + +Some transformed options are: + +- ssl: enable ssl. +- echo: enable echo. +- echo_pool: enable echo for pool. +- pool_size: maximal amount of connections, int (former name: min_size). +- max_overflow: maximal amount of connections, int (former name: max_size). +- pool_recycle: maximal duration a connection may live, float. +- isolation_level: isolation_level, str. + + ## Connection options as a dictionary **Databasez** also provides another way of passing the connection options by using dictionaries. @@ -139,7 +153,7 @@ Databasez expects a python dictionary like object with the following structure. "user": ..., "password": ..., "database": ..., - "options": { + "options": { # only query "driver": ... # In case of MSSQL "ssl": ... } diff --git a/docs/index.md b/docs/index.md index 3bc7747..466f437 100644 --- a/docs/index.md +++ b/docs/index.md @@ -60,7 +60,7 @@ Databasez was built for Python 3.8+ and on the top of the newest **SQLAlchemy 2* simple asyncio support for a range of databases. ### Special notes -This package couldn't exist without [Databases](https://www.encode.io/databasex/) and the continuous work +This package couldn't exist without [Databases](https://www.encode.io/databases/) and the continuous work done by the amazing team behind it. For that reason, thank you! ## Installation @@ -69,24 +69,16 @@ done by the amazing team behind it. For that reason, thank you! $ pip install databasez ``` -If you are interested in using the [test client](./test-client.md), you can also install: - -```shell -$ pip install databasez[testing] -``` +If you are interested in using the [test client](./test-client.md), you can just use it. ## What does databasez support at the moment -Databasez currently supports `sqlite`, `postgres`, `mysql` and `sql server`. More drivers can and -will be added in the future. +Databasez currently supports nearly all async drivers of sqlalchemy. -Database drivers supported are: +If this is not enough there are two special dialects with restricted features: -* [asyncpg][asyncpg] - For postgres. -* [aiomysql][aiomysql] - For MySQL/MariaDB. -* [asyncmy][asyncmy] - For MySQL/MariaDB. -* [aiosqlite][aiosqlite] - For SQLite. -* [aioodbc][aioodbc] - For MSSQL (SQL Server). +- jdbc: can load nearly any jdbc driver +- dbapi2: can load nearly any dbapi2 driver (python standard), async as well as sync. ### Driver installation diff --git a/docs/release-notes.md b/docs/release-notes.md index d55436b..faa7497 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,6 +3,10 @@ ## 0.9.5 +### Changed + +- Extract more options by default from query options. + ### Fixed - `disconnect_hook` was called too early. diff --git a/docs_src/quickstart/quickstart.py b/docs_src/quickstart/quickstart.py index dd2f789..3ae71e1 100644 --- a/docs_src/quickstart/quickstart.py +++ b/docs_src/quickstart/quickstart.py @@ -3,7 +3,8 @@ from databasez import Database -database = Database("sqlite+aiosqlite:///example.db") +# non captured arguments are passed through to create_async_engine +database = Database("sqlite+aiosqlite:///example.db", echo=True) await database.connect() # Create a table.