Skip to content

Commit

Permalink
release with some version compatability fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
joeblackwaslike committed Nov 13, 2023
1 parent ebe5a53 commit 5148172
Show file tree
Hide file tree
Showing 12 changed files with 836 additions and 1,002 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ pytest-plugin-work
old
examples/two/
*.sqlite
*.db
*.db
.pdm-python
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.8.15
3.8.16
1,558 changes: 735 additions & 823 deletions pdm.lock

Large diffs are not rendered by default.

111 changes: 0 additions & 111 deletions pyproject.toml

This file was deleted.

2 changes: 1 addition & 1 deletion src/quart_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
from .extension import SQLAlchemy


__version__ = "2.0.0"
__version__ = "2.0.1"

__all__ = ["SQLAlchemy"]
73 changes: 54 additions & 19 deletions src/quart_sqlalchemy/extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,17 @@ def init_app(self, app: Quart) -> None:

app.shell_context_processor(add_models_to_shell)

basic_uri: str | sa.URL | None = app.config.setdefault("SQLALCHEMY_DATABASE_URI", None)
basic_uri: str | sa.URL | None = app.config.setdefault(
"SQLALCHEMY_DATABASE_URI", None
)
basic_engine_options = self._engine_options.copy()
basic_engine_options.update(app.config.setdefault("SQLALCHEMY_ENGINE_OPTIONS", {}))
echo: bool = app.config.setdefault("SQLALCHEMY_ECHO", False)
config_binds: dict[str | None, str | sa.URL | dict[str, t.Any]] = app.config.setdefault(
"SQLALCHEMY_BINDS", {}
basic_engine_options.update(
app.config.setdefault("SQLALCHEMY_ENGINE_OPTIONS", {})
)
echo: bool = app.config.setdefault("SQLALCHEMY_ECHO", False)
config_binds: dict[
str | None, str | sa.URL | dict[str, t.Any]
] = app.config.setdefault("SQLALCHEMY_BINDS", {})
engine_options: dict[str | None, dict[str, t.Any]] = {}

# Build the engine config for each bind key.
Expand Down Expand Up @@ -406,7 +410,9 @@ def _make_metadata(self, bind_key: str | None) -> sa.MetaData:
naming_convention = None

# Set the bind key in info to be used by session.get_bind.
metadata = sa.MetaData(naming_convention=naming_convention, info={"bind_key": bind_key})
metadata = sa.MetaData(
naming_convention=naming_convention, info={"bind_key": bind_key}
)
self.metadatas[bind_key] = metadata
return metadata

Expand All @@ -419,7 +425,9 @@ def _make_table_class(self) -> type[sa.Table]:
"""

class Table(_Table):
def __new__(cls, *args: t.Any, bind_key: str | None = None, **kwargs: t.Any) -> Table:
def __new__(
cls, *args: t.Any, bind_key: str | None = None, **kwargs: t.Any
) -> Table:
# If a metadata arg is passed, go directly to the base Table. Also do
# this for no args so the correct error is shown.
if not args or (len(args) >= 2 and isinstance(args[1], sa.MetaData)):
Expand All @@ -430,7 +438,9 @@ def __new__(cls, *args: t.Any, bind_key: str | None = None, **kwargs: t.Any) ->

return Table

def _make_declarative_base(self, model: type[Model] | sa.orm.DeclarativeMeta) -> type[t.Any]:
def _make_declarative_base(
self, model: type[CustomModel] | sa.orm.DeclarativeMeta
) -> type[t.Any]:
"""Create a SQLAlchemy declarative model class. The result is available as
:attr:`Model`.
Expand Down Expand Up @@ -556,7 +566,11 @@ def _make_engine(

url = sa.make_url(options["url"])
is_async = url.get_dialect().is_async
factory = sa.ext.asyncio.async_engine_from_config if is_async else sa.engine_from_config
factory = (
sa.ext.asyncio.async_engine_from_config
if is_async
else sa.engine_from_config
)
context = EngineContext(
bind_key=bind_key,
options=options,
Expand Down Expand Up @@ -628,7 +642,9 @@ def get_bind(self, bind_key: t.Optional[str] = None, app: t.Optional[Quart] = No
except RuntimeError:
apps = tuple(app_engines.keys())
if len(apps) > 1:
raise RuntimeError("No application context, multiple applications registered")
raise RuntimeError(
"No application context, multiple applications registered"
)
app = apps[0]
except:
raise RuntimeError("No application context, no application registered")
Expand All @@ -642,13 +658,18 @@ def bind_context(
execution_options: t.Optional[dict[str, t.Any]] = None,
app: t.Optional[Quart] = None,
) -> BindContext:
return BindContext(self, app, bind_key, execution_options=execution_options or {})
return BindContext(
self, app, bind_key, execution_options=execution_options or {}
)

def _get_app_context(self, cache_fallback_enabled: bool = False):
try:
app_context = app_ctx._get_current_object()
except RuntimeError:
if self._context_caching_enabled is False and cache_fallback_enabled is False:
if (
self._context_caching_enabled is False
and cache_fallback_enabled is False
):
raise
app_context = self._last_app_ctx
except:
Expand All @@ -660,12 +681,16 @@ def get_session_scope(self, cache_fallback_enabled: bool = False):
try:
scope = self.session_scopefunc()
except:
app_ctx = self._get_app_context(cache_fallback_enabled=cache_fallback_enabled)
app_ctx = self._get_app_context(
cache_fallback_enabled=cache_fallback_enabled
)
scope = id(app_ctx)

return scope

def _call_for_binds(self, bind_key: str | None | list[str | None], op_name: str) -> None:
def _call_for_binds(
self, bind_key: str | None | list[str | None], op_name: str
) -> None:
"""Call a method on each metadata.
:meta private:
Expand Down Expand Up @@ -710,13 +735,19 @@ def sync_wrapper(_, db, bind_key, op_name):

await conn.run_sync(sync_wrapper, self, bind_key, op_name)

async def async_create_all(self, bind_key: str | None | list[str | None] = "__all__") -> None:
async def async_create_all(
self, bind_key: str | None | list[str | None] = "__all__"
) -> None:
await self._async_call_for_binds(bind_key, "create_all")

async def async_drop_all(self, bind_key: str | None | list[str | None] = "__all__") -> None:
async def async_drop_all(
self, bind_key: str | None | list[str | None] = "__all__"
) -> None:
await self._async_call_for_binds(bind_key, "drop_all")

async def async_reflect(self, bind_key: str | None | list[str | None] = "__all__") -> None:
async def async_reflect(
self, bind_key: str | None | list[str | None] = "__all__"
) -> None:
await self._async_call_for_binds(bind_key, "reflect")

def create_all(self, bind_key: str | None | list[str | None] = "__all__") -> None:
Expand Down Expand Up @@ -768,7 +799,9 @@ def _set_rel_query(self, kwargs: dict[str, t.Any]) -> None:

backref[1].setdefault("query_class", self.Query)

def relationship(self, *args: t.Any, **kwargs: t.Any) -> sa.orm.RelationshipProperty[t.Any]:
def relationship(
self, *args: t.Any, **kwargs: t.Any
) -> sa.orm.RelationshipProperty[t.Any]:
"""A :func:`sqlalchemy.orm.relationship` that applies this extension's
:attr:`Query` class for dynamic relationships and backrefs.
"""
Expand Down Expand Up @@ -838,7 +871,9 @@ class BindContext:
is_async: bool = field(init=False)
engine: sa.Engine | sa.ext.asyncio.AsyncEngine = field(init=False)
metadata: sa.MetaData = field(init=False, repr=False)
connection: sa.Connection | sa.ext.asyncio.AsyncConnection = field(init=False, repr=False)
connection: sa.Connection | sa.ext.asyncio.AsyncConnection = field(
init=False, repr=False
)
session: sa.orm.scoped_session | sa.ext.asyncio.async_scoped_session = field(
init=False, repr=False
)
Expand Down
5 changes: 3 additions & 2 deletions src/quart_sqlalchemy/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ def __init__(self, session: SessionT):
self.session = session

def get(self, entity_id: EntityIdT) -> EntityT:
self.session.delete(entity_id)
self.session.get(entity_id)

def get_by(
self,
clauses: t.Iterable[t.Any] = (),
options: t.Iterable[t.Any] = (),
) -> list[EntityT]:
self.session.delete(entity_id)
statement = sa.select(self.model).where(*clauses).options(*options)
return self.session.scalars(statement).all()

def add(self, entity: EntityT) -> EntityT:
self.session.add(entity)
Expand Down
29 changes: 18 additions & 11 deletions src/quart_sqlalchemy/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import sqlalchemy.orm
from blinker import Namespace
from quart import Quart
from quart.signals import AsyncNamespace
from sqlalchemy.engine import Engine

from .types import AnyCallableType
Expand All @@ -17,13 +16,13 @@

sa = sqlalchemy

sync_signals = Namespace()
async_signals = AsyncNamespace()
_signals = Namespace()

before_engine_created = sync_signals.signal("quart-sqlalchemy.engine.created.before")
after_engine_created = sync_signals.signal("quart-sqlalchemy.engine.created.after")

before_app_initialized = sync_signals.signal(
before_engine_created = _signals.signal("quart-sqlalchemy.engine.created.before")
after_engine_created = _signals.signal("quart-sqlalchemy.engine.created.after")

before_app_initialized = _signals.signal(
"quart-sqlalchemy.app.initialized.before",
doc="""Fired before SQLAlchemy.init_app(app) is called.
Expand All @@ -32,7 +31,7 @@ def handle(sender: SQLAlchemy, app: Quart):
...
""",
)
after_app_initialized = sync_signals.signal(
after_app_initialized = _signals.signal(
"quart-sqlalchemy.app.initialized.after",
doc="""Fired after SQLAlchemy.init_app(app) is called.
Expand All @@ -42,11 +41,19 @@ def handle(sender: SQLAlchemy, app: Quart):
""",
)

before_make_session_factory = sync_signals.signal("quart-sqlalchemy.make-session-factory.before")
after_make_session_factory = sync_signals.signal("quart-sqlalchemy.make-session-factory.after")
before_make_session_factory = _signals.signal(
"quart-sqlalchemy.make-session-factory.before"
)
after_make_session_factory = _signals.signal(
"quart-sqlalchemy.make-session-factory.after"
)

before_make_scoped_session = sync_signals.signal("quart-sqlalchemy.make-scoped-session.before")
after_make_scoped_session = sync_signals.signal("quart-sqlalchemy.make-scoped-session.after")
before_make_scoped_session = _signals.signal(
"quart-sqlalchemy.make-scoped-session.before"
)
after_make_scoped_session = _signals.signal(
"quart-sqlalchemy.make-scoped-session.after"
)


@dataclass
Expand Down
1 change: 1 addition & 0 deletions src/quart_sqlalchemy/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# This package is not finished
Loading

0 comments on commit 5148172

Please sign in to comment.