33import asyncio
44import inspect
55import warnings
6+ import weakref
67from contextvars import ContextVar
7- from typing import Optional
8+ from typing import Optional , Callable , Any
89
910from sqlalchemy import text
1011from sqlalchemy .engine import Engine
2324from sqlalchemy .sql import ClauseElement , WARN_LINTING
2425from sqlalchemy .util .concurrency import greenlet_spawn
2526
27+ from .loader import Loader , LoaderResult
28+
2629
2730async def create_engine (
2831 url , * arg , isolation_level = None , min_size = 1 , max_size = None , ** kw
@@ -212,6 +215,18 @@ async def _execute_sa10(self, object_, multiparams, params):
212215 return await asyncio .wait_for (coro , timeout )
213216 return await coro
214217
218+ def _load_result (self , result ):
219+ options = result .context .execution_options
220+ loader = options .get ("loader" )
221+ model = options .get ("model" )
222+ if loader is None and model is not None :
223+ if isinstance (model , weakref .ref ):
224+ model = model ()
225+ loader = Loader .get (model )
226+ if loader is not None and options .get ("return_model" , True ):
227+ result = LoaderResult (result , loader )
228+ return result
229+
215230 async def _execute (self , object_ , params_20style ):
216231 if isinstance (object_ , str ):
217232 return await self .exec_driver_sql (object_ , params_20style )
@@ -281,6 +296,7 @@ async def all(self, clause, *multiparams, **params):
281296
282297 """
283298 result = await self ._execute_sa10 (clause , multiparams , params )
299+ result = self ._load_result (result )
284300 return result .all ()
285301
286302 async def first (self , clause , * multiparams , ** params ):
@@ -293,6 +309,7 @@ async def first(self, clause, *multiparams, **params):
293309
294310 """
295311 result = await self ._execute_sa10 (clause , multiparams , params )
312+ result = self ._load_result (result )
296313 try :
297314 return result .first ()
298315 except ResourceClosedError as e :
@@ -313,6 +330,7 @@ async def one_or_none(self, clause, *multiparams, **params):
313330
314331 """
315332 result = await self ._execute_sa10 (clause , multiparams , params )
333+ result = self ._load_result (result )
316334 return result .one_or_none ()
317335
318336 async def one (self , clause , * multiparams , ** params ):
@@ -328,6 +346,7 @@ async def one(self, clause, *multiparams, **params):
328346
329347 """
330348 result = await self ._execute_sa10 (clause , multiparams , params )
349+ result = self ._load_result (result )
331350 return result .one ()
332351
333352 async def scalar (self , clause , * multiparams , ** params ):
@@ -352,7 +371,7 @@ async def status(self, clause, *multiparams, **params):
352371
353372 """
354373 result = await self ._execute_sa10 (clause , multiparams , params )
355- return f"SELECT { result .rowcount } " , result . all ()
374+ return result .context
356375
357376 class _IterateResult (StartableContext ):
358377 def __init__ (self , conn , * args ):
@@ -633,6 +652,10 @@ async def status(self, clause, *multiparams, **params):
633652 async with self .acquire (reuse = True ) as conn :
634653 return await conn .status (clause , * multiparams , ** params )
635654
655+ async def run_sync (self , fn : Callable , * arg , ** kw ) -> Any :
656+ async with self .acquire (reuse = True ) as conn :
657+ return await conn .run_sync (fn , * arg , ** kw )
658+
636659 class _CompileConnection :
637660 def __init__ (self , dialect ):
638661 self .dialect = dialect
@@ -737,7 +760,7 @@ def repr(self, color=False):
737760 return repr (self )
738761
739762 def __repr__ (self ):
740- return f' { self .__class__ .__name__ } <{ self .sync_engine .pool .status ()} >'
763+ return f" { self .__class__ .__name__ } <{ self .sync_engine .pool .status ()} >"
741764
742765
743766class AsyncOptionEngine (OptionEngineMixin , GinoEngine ):
0 commit comments