@@ -131,13 +131,15 @@ async def count(
131131 self ,
132132 session : AsyncSession ,
133133 * whereclause : ColumnExpressionArgument [bool ],
134+ join_conditions : JoinConditionsConfig | None = None ,
134135 ** kwargs ,
135136 ) -> int :
136137 """
137138 Count records that match specified filters.
138139
139- :param session: The SQLAlchemy async session
140- :param whereclause: Additional WHERE clauses to apply to the query
140+ :param session: SQLAlchemy async session
141+ :param whereclause: Additional WHERE clauses
142+ :param join_conditions: JOIN conditions for relationships
141143 :param kwargs: Filter expressions using field__operator=value syntax
142144 :return:
143145 """
@@ -150,6 +152,9 @@ async def count(
150152 if filters :
151153 stmt = stmt .where (* filters )
152154
155+ if join_conditions :
156+ stmt = apply_join_conditions (self .model , stmt , join_conditions )
157+
153158 query = await session .execute (stmt )
154159 total_count = query .scalar ()
155160 return total_count if total_count is not None else 0
@@ -158,13 +163,15 @@ async def exists(
158163 self ,
159164 session : AsyncSession ,
160165 * whereclause : ColumnExpressionArgument [bool ],
166+ join_conditions : JoinConditionsConfig | None = None ,
161167 ** kwargs ,
162168 ) -> bool :
163169 """
164170 Check whether records that match the specified filters exist.
165171
166- :param session: The SQLAlchemy async session
167- :param whereclause: Additional WHERE clauses to apply to the query
172+ :param session: SQLAlchemy async session
173+ :param whereclause: Additional WHERE clauses
174+ :param join_conditions: JOIN conditions for relationships
168175 :param kwargs: Filter expressions using field__operator=value syntax
169176 :return:
170177 """
@@ -174,6 +181,10 @@ async def exists(
174181 filters .extend (parse_filters (self .model , ** kwargs ))
175182
176183 stmt = select (self .model ).where (* filters ).limit (1 )
184+
185+ if join_conditions :
186+ stmt = apply_join_conditions (self .model , stmt , join_conditions )
187+
177188 query = await session .execute (stmt )
178189 return query .scalars ().first () is not None
179190
@@ -241,44 +252,60 @@ async def select_model_by_column(
241252 :param kwargs: Filter expressions using field__operator=value syntax
242253 :return:
243254 """
244- filters = list (whereclause )
245-
246- if kwargs :
247- filters .extend (parse_filters (self .model , ** kwargs ))
248-
249- stmt = select (self .model ).where (* filters )
250-
251- if options :
252- stmt = stmt .options (* options )
253-
254- if join_conditions :
255- stmt = apply_join_conditions (self .model , stmt , join_conditions )
256-
257- if load_strategies :
258- rel_options = build_load_strategies (self .model , load_strategies )
259- if rel_options :
260- stmt = stmt .options (* rel_options )
255+ stmt = await self .select (
256+ * whereclause ,
257+ options = options ,
258+ load_strategies = load_strategies ,
259+ join_conditions = join_conditions ,
260+ ** kwargs
261+ )
261262
262263 query = await session .execute (stmt )
263264 return query .scalars ().first ()
264265
265- async def select (self , * whereclause : ColumnExpressionArgument [bool ], ** kwargs ) -> Select :
266+ async def select (
267+ self ,
268+ * whereclause : ColumnExpressionArgument [bool ],
269+ options : QueryOptions | None = None ,
270+ load_strategies : LoadStrategiesConfig | None = None ,
271+ join_conditions : JoinConditionsConfig | None = None ,
272+ ** kwargs
273+ ) -> Select :
266274 """
267275 Construct the SQLAlchemy selection.
268276
269277 :param whereclause: WHERE clauses to apply to the query
278+ :param options: SQLAlchemy loading options
279+ :param load_strategies: Relationship loading strategies
280+ :param join_conditions: JOIN conditions for relationships
270281 :param kwargs: Query expressions
271282 :return:
272283 """
273- filters = parse_filters (self .model , ** kwargs ) + list (whereclause )
284+ filters = list (whereclause )
285+ filters .extend (parse_filters (self .model , ** kwargs ))
274286 stmt = select (self .model ).where (* filters )
287+
288+ if join_conditions :
289+ stmt = apply_join_conditions (self .model , stmt , join_conditions )
290+
291+ if options :
292+ stmt = stmt .options (* options )
293+
294+ if load_strategies :
295+ rel_options = build_load_strategies (self .model , load_strategies )
296+ if rel_options :
297+ stmt = stmt .options (* rel_options )
298+
275299 return stmt
276300
277301 async def select_order (
278302 self ,
279303 sort_columns : SortColumns ,
280304 sort_orders : SortOrders = None ,
281305 * whereclause : ColumnExpressionArgument [bool ],
306+ options : QueryOptions | None = None ,
307+ load_strategies : LoadStrategiesConfig | None = None ,
308+ join_conditions : JoinConditionsConfig | None = None ,
282309 ** kwargs : Any ,
283310 ) -> Select :
284311 """
@@ -287,10 +314,19 @@ async def select_order(
287314 :param sort_columns: Column names to sort by
288315 :param sort_orders: Sort orders ('asc' or 'desc')
289316 :param whereclause: WHERE clauses to apply to the query
317+ :param options: SQLAlchemy loading options
318+ :param load_strategies: Relationship loading strategies
319+ :param join_conditions: JOIN conditions for relationships
290320 :param kwargs: Query expressions
291321 :return:
292322 """
293- stmt = await self .select (* whereclause , ** kwargs )
323+ stmt = await self .select (
324+ * whereclause ,
325+ options = options ,
326+ load_strategies = load_strategies ,
327+ join_conditions = join_conditions ,
328+ ** kwargs
329+ )
294330 sorted_stmt = apply_sorting (self .model , stmt , sort_columns , sort_orders )
295331 return sorted_stmt
296332
@@ -306,7 +342,7 @@ async def select_models(
306342 ** kwargs : Any ,
307343 ) -> Sequence [Model ]:
308344 """
309- Query all rows that match the specified filters with optional relationship loading and joins.
345+ Query all rows that match the specified filters with optional relationship loading and joins.
310346
311347 :param session: SQLAlchemy async session
312348 :param whereclause: Additional WHERE clauses
@@ -318,18 +354,13 @@ async def select_models(
318354 :param kwargs: Filter expressions using field__operator=value syntax
319355 :return:
320356 """
321- stmt = await self .select (* whereclause , ** kwargs )
322-
323- if options :
324- stmt = stmt .options (* options )
325-
326- if join_conditions :
327- stmt = apply_join_conditions (self .model , stmt , join_conditions )
328-
329- if load_strategies :
330- rel_options = build_load_strategies (self .model , load_strategies )
331- if rel_options :
332- stmt = stmt .options (* rel_options )
357+ stmt = await self .select (
358+ * whereclause ,
359+ options = options ,
360+ load_strategies = load_strategies ,
361+ join_conditions = join_conditions ,
362+ ** kwargs
363+ )
333364
334365 if limit is not None :
335366 stmt = stmt .limit (limit )
@@ -368,18 +399,15 @@ async def select_models_order(
368399 :param kwargs: Filter expressions using field__operator=value syntax
369400 :return:
370401 """
371- stmt = await self .select_order (sort_columns , sort_orders , * whereclause , ** kwargs )
372-
373- if options :
374- stmt = stmt .options (* options )
375-
376- if join_conditions :
377- stmt = apply_join_conditions (self .model , stmt , join_conditions )
378-
379- if load_strategies :
380- rel_options = build_load_strategies (self .model , load_strategies )
381- if rel_options :
382- stmt = stmt .options (* rel_options )
402+ stmt = await self .select_order (
403+ sort_columns ,
404+ sort_orders ,
405+ * whereclause ,
406+ options = options ,
407+ load_strategies = load_strategies ,
408+ join_conditions = join_conditions ,
409+ ** kwargs
410+ )
383411
384412 if limit is not None :
385413 stmt = stmt .limit (limit )
0 commit comments