sqla-fancy-core 1.1.0__py3-none-any.whl → 1.1.2__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 sqla-fancy-core might be problematic. Click here for more details.
- sqla_fancy_core/decorators.py +50 -14
- {sqla_fancy_core-1.1.0.dist-info → sqla_fancy_core-1.1.2.dist-info}/METADATA +5 -6
- sqla_fancy_core-1.1.2.dist-info/RECORD +8 -0
- sqla_fancy_core-1.1.0.dist-info/RECORD +0 -8
- {sqla_fancy_core-1.1.0.dist-info → sqla_fancy_core-1.1.2.dist-info}/WHEEL +0 -0
- {sqla_fancy_core-1.1.0.dist-info → sqla_fancy_core-1.1.2.dist-info}/licenses/LICENSE +0 -0
sqla_fancy_core/decorators.py
CHANGED
|
@@ -7,7 +7,9 @@ from typing import Union, overload
|
|
|
7
7
|
import sqlalchemy as sa
|
|
8
8
|
from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
from sqla_fancy_core.wrappers import AsyncFancyEngineWrapper, FancyEngineWrapper
|
|
11
|
+
|
|
12
|
+
EngineType = Union[sa.Engine, AsyncEngine, FancyEngineWrapper, AsyncFancyEngineWrapper]
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class _Injectable:
|
|
@@ -16,9 +18,9 @@ class _Injectable:
|
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
@overload
|
|
19
|
-
def Inject(engine: sa.Engine) -> sa.Connection: ...
|
|
21
|
+
def Inject(engine: Union[sa.Engine, FancyEngineWrapper]) -> sa.Connection: ...
|
|
20
22
|
@overload
|
|
21
|
-
def Inject(engine: AsyncEngine) -> AsyncConnection: ...
|
|
23
|
+
def Inject(engine: Union[AsyncEngine, AsyncFancyEngineWrapper]) -> AsyncConnection: ...
|
|
22
24
|
def Inject(engine: EngineType): # type: ignore
|
|
23
25
|
"""A marker class for dependency injection."""
|
|
24
26
|
return _Injectable(engine)
|
|
@@ -44,7 +46,6 @@ def transact(func):
|
|
|
44
46
|
create_user(name="existing", conn=conn)
|
|
45
47
|
"""
|
|
46
48
|
|
|
47
|
-
# Find the parameter with value Inject
|
|
48
49
|
sig = inspect.signature(func)
|
|
49
50
|
inject_param_name = None
|
|
50
51
|
for name, param in sig.parameters.items():
|
|
@@ -56,8 +57,21 @@ def transact(func):
|
|
|
56
57
|
if inject_param_name is None:
|
|
57
58
|
return func # No injection needed
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
engine_arg = sig.parameters[inject_param_name].default.engine
|
|
61
|
+
if isinstance(engine_arg, sa.Engine):
|
|
62
|
+
is_async = False
|
|
63
|
+
engine = engine_arg
|
|
64
|
+
elif isinstance(engine_arg, FancyEngineWrapper):
|
|
65
|
+
is_async = False
|
|
66
|
+
engine = engine_arg.engine
|
|
67
|
+
elif isinstance(engine_arg, AsyncEngine):
|
|
68
|
+
is_async = True
|
|
69
|
+
engine = engine_arg
|
|
70
|
+
elif isinstance(engine_arg, AsyncFancyEngineWrapper):
|
|
71
|
+
is_async = True
|
|
72
|
+
engine = engine_arg.engine
|
|
73
|
+
else:
|
|
74
|
+
raise TypeError("Unsupported engine type")
|
|
61
75
|
|
|
62
76
|
if is_async:
|
|
63
77
|
|
|
@@ -70,8 +84,14 @@ def transact(func):
|
|
|
70
84
|
else:
|
|
71
85
|
async with conn.begin():
|
|
72
86
|
return await func(*args, **kwargs)
|
|
87
|
+
elif isinstance(conn, sa.Connection):
|
|
88
|
+
if conn.in_transaction():
|
|
89
|
+
return await func(*args, **kwargs)
|
|
90
|
+
else:
|
|
91
|
+
with conn.begin():
|
|
92
|
+
return await func(*args, **kwargs)
|
|
73
93
|
else:
|
|
74
|
-
async with engine.begin() as conn:
|
|
94
|
+
async with engine.begin() as conn: # type: ignore
|
|
75
95
|
kwargs[inject_param_name] = conn
|
|
76
96
|
return await func(*args, **kwargs)
|
|
77
97
|
|
|
@@ -88,8 +108,10 @@ def transact(func):
|
|
|
88
108
|
else:
|
|
89
109
|
with conn.begin():
|
|
90
110
|
return func(*args, **kwargs)
|
|
111
|
+
elif isinstance(conn, AsyncConnection):
|
|
112
|
+
raise TypeError("AsyncConnection cannot be used in sync function")
|
|
91
113
|
else:
|
|
92
|
-
with engine.begin() as conn:
|
|
114
|
+
with engine.begin() as conn: # type: ignore
|
|
93
115
|
kwargs[inject_param_name] = conn
|
|
94
116
|
return func(*args, **kwargs)
|
|
95
117
|
|
|
@@ -116,7 +138,6 @@ def connect(func):
|
|
|
116
138
|
count = get_user_count(conn)
|
|
117
139
|
"""
|
|
118
140
|
|
|
119
|
-
# Find the parameter with value Inject
|
|
120
141
|
sig = inspect.signature(func)
|
|
121
142
|
inject_param_name = None
|
|
122
143
|
for name, param in sig.parameters.items():
|
|
@@ -128,18 +149,31 @@ def connect(func):
|
|
|
128
149
|
if inject_param_name is None:
|
|
129
150
|
return func # No injection needed
|
|
130
151
|
|
|
131
|
-
|
|
132
|
-
|
|
152
|
+
engine_arg = sig.parameters[inject_param_name].default.engine
|
|
153
|
+
if isinstance(engine_arg, sa.Engine):
|
|
154
|
+
is_async = False
|
|
155
|
+
engine = engine_arg
|
|
156
|
+
elif isinstance(engine_arg, FancyEngineWrapper):
|
|
157
|
+
is_async = False
|
|
158
|
+
engine = engine_arg.engine
|
|
159
|
+
elif isinstance(engine_arg, AsyncEngine):
|
|
160
|
+
is_async = True
|
|
161
|
+
engine = engine_arg
|
|
162
|
+
elif isinstance(engine_arg, AsyncFancyEngineWrapper):
|
|
163
|
+
is_async = True
|
|
164
|
+
engine = engine_arg.engine
|
|
165
|
+
else:
|
|
166
|
+
raise TypeError("Unsupported engine type")
|
|
133
167
|
|
|
134
168
|
if is_async:
|
|
135
169
|
|
|
136
170
|
@functools.wraps(func)
|
|
137
171
|
async def async_wrapper(*args, **kwargs):
|
|
138
172
|
conn = kwargs.get(inject_param_name)
|
|
139
|
-
if isinstance(conn, AsyncConnection):
|
|
173
|
+
if isinstance(conn, (AsyncConnection, sa.Connection)):
|
|
140
174
|
return await func(*args, **kwargs)
|
|
141
175
|
else:
|
|
142
|
-
async with engine.connect() as conn:
|
|
176
|
+
async with engine.connect() as conn: # type: ignore
|
|
143
177
|
kwargs[inject_param_name] = conn
|
|
144
178
|
return await func(*args, **kwargs)
|
|
145
179
|
|
|
@@ -152,8 +186,10 @@ def connect(func):
|
|
|
152
186
|
conn = kwargs.get(inject_param_name)
|
|
153
187
|
if isinstance(conn, sa.Connection):
|
|
154
188
|
return func(*args, **kwargs)
|
|
189
|
+
elif isinstance(conn, AsyncConnection):
|
|
190
|
+
raise TypeError("AsyncConnection cannot be used in sync function")
|
|
155
191
|
else:
|
|
156
|
-
with engine.connect() as conn:
|
|
192
|
+
with engine.connect() as conn: # type: ignore
|
|
157
193
|
kwargs[inject_param_name] = conn
|
|
158
194
|
return func(*args, **kwargs)
|
|
159
195
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqla-fancy-core
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: SQLAlchemy core, but fancier
|
|
5
5
|
Project-URL: Homepage, https://github.com/sayanarijit/sqla-fancy-core
|
|
6
6
|
Author-email: Arijit Basu <sayanarijit@gmail.com>
|
|
@@ -242,27 +242,24 @@ users = sa.Table(
|
|
|
242
242
|
)
|
|
243
243
|
metadata.create_all(engine)
|
|
244
244
|
|
|
245
|
-
# 1) Ensure a connection is available (no implicit transaction)
|
|
246
245
|
@connect
|
|
247
246
|
def get_user_count(conn=Inject(engine)):
|
|
248
247
|
return conn.execute(sa.select(sa.func.count()).select_from(users)).scalar_one()
|
|
249
248
|
|
|
250
249
|
assert get_user_count() == 0
|
|
251
250
|
|
|
252
|
-
# 2) Wrap in a transaction automatically
|
|
253
251
|
@transact
|
|
254
252
|
def create_user(name: str, conn=Inject(engine)):
|
|
255
253
|
conn.execute(sa.insert(users).values(name=name))
|
|
256
254
|
|
|
255
|
+
# Without an explicit transaction
|
|
257
256
|
create_user("alice")
|
|
258
257
|
assert get_user_count() == 1
|
|
259
258
|
|
|
260
|
-
#
|
|
259
|
+
# With an explicit transaction
|
|
261
260
|
with engine.begin() as txn:
|
|
262
261
|
create_user("bob", conn=txn)
|
|
263
262
|
assert get_user_count(conn=txn) == 2
|
|
264
|
-
|
|
265
|
-
assert get_user_count() == 2
|
|
266
263
|
```
|
|
267
264
|
|
|
268
265
|
### Async examples
|
|
@@ -293,10 +290,12 @@ async def get_user_count(conn=Inject(engine)):
|
|
|
293
290
|
async def create_user(name: str, conn=Inject(engine)):
|
|
294
291
|
await conn.execute(sa.insert(users).values(name=name))
|
|
295
292
|
|
|
293
|
+
# Without an explicit transaction
|
|
296
294
|
assert await get_user_count() == 0
|
|
297
295
|
await create_user("carol")
|
|
298
296
|
assert await get_user_count() == 1
|
|
299
297
|
|
|
298
|
+
# With an explicit transaction
|
|
300
299
|
async with engine.connect() as conn:
|
|
301
300
|
await create_user("dave", conn=conn)
|
|
302
301
|
assert await get_user_count(conn=conn) == 2
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
sqla_fancy_core/__init__.py,sha256=iCfZrKbdoAG65CeHGducjiA1p4zYLgFSrxGDzQEhM8U,256
|
|
2
|
+
sqla_fancy_core/decorators.py,sha256=VhkYf5x6qwcQnc8QCuUzKPQxMI3tNNGM7nVSPUqMkPw,6649
|
|
3
|
+
sqla_fancy_core/factories.py,sha256=EgOhc15rCo9GyIuSNhuoB1pJ6lXx_UtRR5y9hh2lEtM,6326
|
|
4
|
+
sqla_fancy_core/wrappers.py,sha256=TesGKm9ddsd7dJwbkonZPl46Huvqeh7AfUwB623qRwA,8165
|
|
5
|
+
sqla_fancy_core-1.1.2.dist-info/METADATA,sha256=dWdZEq6fwzkvrK9zoYpAdh5QQLtMd1lc5NATrp2-1Yo,14419
|
|
6
|
+
sqla_fancy_core-1.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
+
sqla_fancy_core-1.1.2.dist-info/licenses/LICENSE,sha256=XcYXJ0ipvwOn-nzko6p_xoCCbke8tAhmlIN04rUZDLk,1068
|
|
8
|
+
sqla_fancy_core-1.1.2.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
sqla_fancy_core/__init__.py,sha256=iCfZrKbdoAG65CeHGducjiA1p4zYLgFSrxGDzQEhM8U,256
|
|
2
|
-
sqla_fancy_core/decorators.py,sha256=0UlOL2MUAJq3Rv3hE7mLspvrZDX16f2pm_yh1mLgQWQ,5056
|
|
3
|
-
sqla_fancy_core/factories.py,sha256=EgOhc15rCo9GyIuSNhuoB1pJ6lXx_UtRR5y9hh2lEtM,6326
|
|
4
|
-
sqla_fancy_core/wrappers.py,sha256=TesGKm9ddsd7dJwbkonZPl46Huvqeh7AfUwB623qRwA,8165
|
|
5
|
-
sqla_fancy_core-1.1.0.dist-info/METADATA,sha256=1imY4gioOlMMTxS3GBit_-eUSGz71_ArMl9D7WWMxxU,14473
|
|
6
|
-
sqla_fancy_core-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
7
|
-
sqla_fancy_core-1.1.0.dist-info/licenses/LICENSE,sha256=XcYXJ0ipvwOn-nzko6p_xoCCbke8tAhmlIN04rUZDLk,1068
|
|
8
|
-
sqla_fancy_core-1.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|