0.6.1 pypi name change
This commit is contained in:
parent
886da11ade
commit
da0caadf08
6 changed files with 39 additions and 22 deletions
|
|
@ -1,8 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
## 0.6.1
|
||||
|
||||
- First release on PyPI under the name `suou`.
|
||||
- Fix `sqlalchemy.asyncio.SQLAlchemy()` to use context vars; `expire_on_commit=` is now configurable at instantiation. Fix some missing re-exports.
|
||||
|
||||
## 0.6.0
|
||||
|
||||
+ `.sqlalchemy` has been made a subpackage and split; `sqlalchemy_async` has been deprecated. Update your imports.
|
||||
+ `.sqlalchemy` has been made a subpackage and split; `sqlalchemy_async` (moved to `sqlalchemy.asyncio`) has been deprecated. Update your imports.
|
||||
+ Add several new utilities to `.sqlalchemy`: `BitSelector`, `secret_column`, `a_relationship`, `SessionWrapper`,
|
||||
`wrap=` argument to SQLAlchemy. Also removed dead batteries
|
||||
+ Add `.waiter` module. For now, non-functional ~
|
||||
|
|
|
|||
1
aliases/sakuragasaki46-suou/pyproject.toml
Normal file
1
aliases/sakuragasaki46-suou/pyproject.toml
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
[project]
|
||||
name = "sakuragasaki46_suou"
|
||||
name = "suou"
|
||||
description = "casual utility library for coding QoL"
|
||||
authors = [
|
||||
{ name = "Sakuragasaki46" }
|
||||
]
|
||||
|
|
@ -30,7 +31,7 @@ classifiers = [
|
|||
]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/sakuragasaki46/suou"
|
||||
Repository = "https://nekode.yusur.moe/yusur/suou"
|
||||
|
||||
[project.optional-dependencies]
|
||||
# the below are all dev dependencies (and probably already installed)
|
||||
|
|
@ -62,13 +63,13 @@ sass = [
|
|||
]
|
||||
|
||||
full = [
|
||||
"sakuragasaki46-suou[sqlalchemy]",
|
||||
"sakuragasaki46-suou[flask]",
|
||||
"sakuragasaki46-suou[quart]",
|
||||
"sakuragasaki46-suou[peewee]",
|
||||
"sakuragasaki46-suou[markdown]",
|
||||
"sakuragasaki46-suou[flask-sqlalchemy]",
|
||||
"sakuragasaki46-suou[sass]"
|
||||
"suou[sqlalchemy]",
|
||||
"suou[flask]",
|
||||
"suou[quart]",
|
||||
"suou[peewee]",
|
||||
"suou[markdown]",
|
||||
"suou[flask-sqlalchemy]",
|
||||
"suou[sass]"
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ from .validators import matches
|
|||
from .redact import redact_url_password
|
||||
from .http import WantsContentType
|
||||
|
||||
__version__ = "0.6.0"
|
||||
__version__ = "0.6.1"
|
||||
|
||||
__all__ = (
|
||||
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ def require_auth_base(cls: type[DeclarativeBase], *, src: AuthSrc, column: str |
|
|||
|
||||
from .asyncio import SQLAlchemy, AsyncSelectPagination, async_query
|
||||
from .orm import (
|
||||
id_column, snowflake_column, match_column, match_constraint, bool_column, declarative_base,
|
||||
id_column, snowflake_column, match_column, match_constraint, bool_column, declarative_base, parent_children,
|
||||
author_pair, age_pair, bound_fk, unbound_fk, want_column, a_relationship, BitSelector, secret_column
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
from __future__ import annotations
|
||||
from functools import wraps
|
||||
|
||||
|
||||
from sqlalchemy import Engine, Select, Table, func, select
|
||||
from contextvars import ContextVar, Token
|
||||
from sqlalchemy import Select, Table, func, select
|
||||
from sqlalchemy.orm import DeclarativeBase, lazyload
|
||||
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
|
||||
from flask_sqlalchemy.pagination import Pagination
|
||||
|
||||
from suou.classtools import MISSING
|
||||
from suou.exceptions import NotFoundError
|
||||
|
||||
class SQLAlchemy:
|
||||
|
|
@ -45,36 +46,44 @@ class SQLAlchemy:
|
|||
NEW 0.5.0
|
||||
|
||||
UPDATED 0.6.0: added wrap=True
|
||||
|
||||
UPDATED 0.6.1: expire_on_commit is now configurable per-SQLAlchemy();
|
||||
now sessions are stored as context variables
|
||||
"""
|
||||
base: DeclarativeBase
|
||||
engine: AsyncEngine
|
||||
_sessions: list[AsyncSession]
|
||||
_session_tok: list[Token[AsyncSession]]
|
||||
_wrapsessions: bool
|
||||
_xocommit: bool
|
||||
NotFound = NotFoundError
|
||||
|
||||
def __init__(self, model_class: DeclarativeBase, *, wrap = False):
|
||||
def __init__(self, model_class: DeclarativeBase, *, expire_on_commit = False, wrap = False):
|
||||
self.base = model_class
|
||||
self.engine = None
|
||||
self._wrapsessions = wrap
|
||||
self._sessions = []
|
||||
self._xocommit = expire_on_commit
|
||||
def bind(self, url: str):
|
||||
self.engine = create_async_engine(url)
|
||||
def _ensure_engine(self):
|
||||
if self.engine is None:
|
||||
raise RuntimeError('database is not connected')
|
||||
async def begin(self, *, expire_on_commit = False, wrap = False, **kw) -> AsyncSession:
|
||||
async def begin(self, *, expire_on_commit = None, wrap = False, **kw) -> AsyncSession:
|
||||
self._ensure_engine()
|
||||
## XXX is it accurate?
|
||||
s = AsyncSession(self.engine, expire_on_commit=expire_on_commit, **kw)
|
||||
s = AsyncSession(self.engine,
|
||||
expire_on_commit=expire_on_commit if expire_on_commit is not None else self._xocommit,
|
||||
**kw)
|
||||
if wrap:
|
||||
s = SessionWrapper(s)
|
||||
self._sessions.append(s)
|
||||
current_session.set(s)
|
||||
return s
|
||||
async def __aenter__(self) -> AsyncSession:
|
||||
return await self.begin()
|
||||
async def __aexit__(self, e1, e2, e3):
|
||||
## XXX is it accurate?
|
||||
s = self._sessions.pop()
|
||||
s = current_session.get()
|
||||
if not s:
|
||||
raise RuntimeError('session not closed')
|
||||
if e1:
|
||||
await s.rollback()
|
||||
else:
|
||||
|
|
@ -104,7 +113,8 @@ class SQLAlchemy:
|
|||
self.engine, checkfirst=checkfirst
|
||||
)
|
||||
|
||||
|
||||
# XXX NOT public API! DO NOT USE
|
||||
current_session: ContextVar[AsyncSession] = ContextVar('current_session')
|
||||
|
||||
class AsyncSelectPagination(Pagination):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue