Skip to content

Commit

Permalink
fix: add create_engine() method to SQLAlchemy configs. (#2382)
Browse files Browse the repository at this point in the history
* fix: add `create_engine()` method to SQLAlchemy configs.

This PR fixes a break in backward compatibility where the `create_engine()`
method was removed from the SQLAlchemy config types in a minor version
increment.

* fixes doc references.
  • Loading branch information
peterschutt authored Sep 30, 2023
1 parent 2d7ad67 commit 1b47eec
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
(PY_CLASS, "NoneType"),
(PY_CLASS, "litestar._openapi.schema_generation.schema.SchemaCreator"),
(PY_CLASS, "litestar._signature.model.SignatureModel"),
(PY_CLASS, "litestar.contrib.sqlalchemy.plugins.init.config.compat._CreateEngineMixin"),
(PY_CLASS, "litestar.utils.signature.ParsedSignature"),
(PY_CLASS, "litestar.utils.sync.AsyncCallable"),
# types in changelog that no longer exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ Renaming the dependencies
#########################

You can change the name that the engine and session are bound to by setting the
:attr:`engine_dependency_key` and :attr:`session_dependency_key`
:attr:`engine_dependency_key <advanced_alchemy.extensions.litestar.plugins.init.config.asyncio.SQLAlchemyAsyncConfig.engine_dependency_key>`
and :attr:`session_dependency_key <advanced_alchemy.extensions.litestar.plugins.init.config.asyncio.SQLAlchemyAsyncConfig.session_dependency_key>`
attributes on the plugin configuration.

Configuring the before send handler
Expand All @@ -49,9 +50,9 @@ The plugin configures a ``before_send`` handler that is called before sending a
session and removes it from the connection scope.

You can change the handler by setting the
:attr:`before_send_handler` attribute
on the configuration object. For example, an alternate handler is available that will also commit the session on success
and rollback upon failure.
:attr:`before_send_handler <advanced_alchemy.extensions.litestar.plugins.init.config.asyncio.SQLAlchemyAsyncConfig.before_send_handler>`
attribute on the configuration object. For example, an alternate handler is available that will also commit the session
on success and rollback upon failure.

.. tab-set::

Expand Down
11 changes: 10 additions & 1 deletion litestar/contrib/sqlalchemy/plugins/init/config/asyncio.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

from advanced_alchemy.config.asyncio import AlembicAsyncConfig, AsyncSessionConfig
from advanced_alchemy.extensions.litestar.plugins.init.config.asyncio import (
SQLAlchemyAsyncConfig,
SQLAlchemyAsyncConfig as _SQLAlchemyAsyncConfig,
)
from advanced_alchemy.extensions.litestar.plugins.init.config.asyncio import (
autocommit_before_send_handler,
default_before_send_handler,
)
from sqlalchemy.ext.asyncio import AsyncEngine

from litestar.contrib.sqlalchemy.plugins.init.config.compat import _CreateEngineMixin

__all__ = (
"SQLAlchemyAsyncConfig",
Expand All @@ -14,3 +19,7 @@
"default_before_send_handler",
"autocommit_before_send_handler",
)


class SQLAlchemyAsyncConfig(_SQLAlchemyAsyncConfig, _CreateEngineMixin[AsyncEngine]):
...
23 changes: 23 additions & 0 deletions litestar/contrib/sqlalchemy/plugins/init/config/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from __future__ import annotations

from typing import TYPE_CHECKING, Generic, Protocol, TypeVar

from litestar.utils.deprecation import deprecated

if TYPE_CHECKING:
from sqlalchemy import Engine
from sqlalchemy.ext.asyncio import AsyncEngine


EngineT_co = TypeVar("EngineT_co", bound="Engine | AsyncEngine", covariant=True)


class HasGetEngine(Protocol[EngineT_co]):
def get_engine(self) -> EngineT_co:
...


class _CreateEngineMixin(Generic[EngineT_co]):
@deprecated(version="2.1.1", removal_in="3.0.0", alternative="get_engine()")
def create_engine(self: HasGetEngine[EngineT_co]) -> EngineT_co:
return self.get_engine()
11 changes: 10 additions & 1 deletion litestar/contrib/sqlalchemy/plugins/init/config/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

from advanced_alchemy.config.sync import AlembicSyncConfig, SyncSessionConfig
from advanced_alchemy.extensions.litestar.plugins.init.config.sync import (
SQLAlchemySyncConfig,
SQLAlchemySyncConfig as _SQLAlchemySyncConfig,
)
from advanced_alchemy.extensions.litestar.plugins.init.config.sync import (
autocommit_before_send_handler,
default_before_send_handler,
)
from sqlalchemy import Engine

from litestar.contrib.sqlalchemy.plugins.init.config.compat import _CreateEngineMixin

__all__ = (
"SQLAlchemySyncConfig",
Expand All @@ -14,3 +19,7 @@
"default_before_send_handler",
"autocommit_before_send_handler",
)


class SQLAlchemySyncConfig(_SQLAlchemySyncConfig, _CreateEngineMixin[Engine]):
...
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from __future__ import annotations

import pytest
from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine

from litestar.contrib.sqlalchemy.plugins.init.config.asyncio import SQLAlchemyAsyncConfig


def test_create_engine_with_engine_instance() -> None:
engine = create_async_engine("sqlite+aiosqlite:///:memory:")
config = SQLAlchemyAsyncConfig(engine_instance=engine)
with pytest.deprecated_call():
assert engine is config.create_engine()


def test_create_engine_with_connection_string() -> None:
config = SQLAlchemyAsyncConfig(connection_string="sqlite+aiosqlite:///:memory:")
with pytest.deprecated_call():
engine = config.create_engine()
assert isinstance(engine, AsyncEngine)
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from __future__ import annotations

import pytest
from sqlalchemy import Engine, create_engine

from litestar.contrib.sqlalchemy.plugins.init.config.sync import SQLAlchemySyncConfig


def test_create_engine_with_engine_instance() -> None:
engine = create_engine("sqlite:///:memory:")
config = SQLAlchemySyncConfig(engine_instance=engine)
with pytest.deprecated_call():
assert engine is config.create_engine()


def test_create_engine_with_connection_string() -> None:
config = SQLAlchemySyncConfig(connection_string="sqlite:///:memory:")
with pytest.deprecated_call():
engine = config.create_engine()
assert isinstance(engine, Engine)

0 comments on commit 1b47eec

Please sign in to comment.