aiteamutils 0.2.163__py3-none-any.whl → 0.2.165__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.
aiteamutils/database.py CHANGED
@@ -12,7 +12,7 @@ from typing import (
12
12
  Tuple
13
13
  )
14
14
  from sqlalchemy.ext.asyncio import AsyncSession
15
- from sqlalchemy import select, and_, or_
15
+ from sqlalchemy import select, and_, or_, join
16
16
  from sqlalchemy.orm import DeclarativeBase, joinedload, selectinload, contains_eager
17
17
  from sqlalchemy.exc import SQLAlchemyError
18
18
  from datetime import datetime
@@ -30,8 +30,7 @@ ModelType = TypeVar("ModelType", bound=DeclarativeBase)
30
30
 
31
31
  JoinTarget = Union[
32
32
  DeclarativeBase, # 모델
33
- Tuple[DeclarativeBase, BinaryExpression], # (모델, 조인 조건)
34
- Tuple[DeclarativeBase, BinaryExpression, str] # (모델, 조인 조건, 조인 타입)
33
+ Tuple[DeclarativeBase, BinaryExpression] # (모델, 조인 조건)
35
34
  ]
36
35
 
37
36
  ##################
@@ -263,61 +262,6 @@ def build_conditions(
263
262
  ##################
264
263
  # 쿼리 실행 #
265
264
  ##################
266
- async def execute_query(
267
- session: AsyncSession,
268
- model: Type[ModelType],
269
- explicit_joins: Optional[List[JoinTarget]] = None,
270
- loading_joins: Optional[List[Any]] = None,
271
- conditions: Optional[List[BinaryExpression]] = None,
272
- ) -> Select:
273
- """
274
- 쿼리 실행을 위한 공통 함수
275
-
276
- Args:
277
- session: 데이터베이스 세션
278
- model: 기본 모델
279
- explicit_joins: 명시적 조인 설정
280
- - 모델만 전달: 기본 outer join
281
- - (모델, 조건): 조건부 outer join
282
- - (모델, 조건, 'inner'/'left'/'right'): 조인 타입 지정
283
- loading_joins: Relationship 로딩 설정 (joinedload, selectinload 등)
284
- conditions: WHERE 조건들
285
- """
286
- # 1. 기본 쿼리 생성
287
- query = select(model)
288
-
289
- # 2. 명시적 조인 처리
290
- if explicit_joins:
291
- for join_target in explicit_joins:
292
- if isinstance(join_target, DeclarativeBase):
293
- # 모델만 전달된 경우
294
- query = query.outerjoin(join_target)
295
- elif isinstance(join_target, tuple):
296
- if len(join_target) == 2:
297
- # (모델, 조건)이 전달된 경우
298
- target_model, join_condition = join_target
299
- query = query.outerjoin(target_model, join_condition)
300
- elif len(join_target) == 3:
301
- # (모델, 조건, 조인타입)이 전달된 경우
302
- target_model, join_condition, join_type = join_target
303
- if join_type == 'inner':
304
- query = query.join(target_model, join_condition)
305
- elif join_type == 'left':
306
- query = query.outerjoin(target_model, join_condition)
307
- elif join_type == 'right':
308
- query = query.outerjoin(target_model, join_condition, full=True)
309
-
310
- # 3. Relationship 로딩 설정
311
- if loading_joins:
312
- for join_option in loading_joins:
313
- query = query.options(join_option)
314
-
315
- # 4. 조건 적용
316
- if conditions:
317
- query = query.where(and_(*conditions))
318
-
319
- return query
320
-
321
265
  async def create_entity(
322
266
  session: AsyncSession,
323
267
  model: Type[ModelType],
@@ -495,18 +439,48 @@ async def list_entities(
495
439
  loading_joins: Optional[List[Any]] = None,
496
440
  order: Optional[List[Dict[str, str]]] = None
497
441
  ) -> List[Dict[str, Any]]:
442
+ """
443
+ 엔터티 리스트를 필터 및 조건에 따라 가져오는 함수.
444
+
445
+ Args:
446
+ session: SQLAlchemy AsyncSession.
447
+ model: SQLAlchemy 모델.
448
+ skip: 페이지네이션 시작 위치.
449
+ limit: 페이지네이션 크기.
450
+ filters: 필터 조건 딕셔너리.
451
+ explicit_joins: 명시적 조인 대상 리스트
452
+ - 모델만 전달: 기본 outer join
453
+ - (모델, 조인조건): 조건부 outer join
454
+ loading_joins: 로딩 조인 옵션 리스트 (joinedload, selectinload 등)
455
+ order: 정렬 조건 리스트
456
+
457
+ Returns:
458
+ List[Dict[str, Any]]: 쿼리 결과 리스트.
459
+ """
498
460
  try:
499
- # 필터 조건 생성
500
- conditions = build_conditions(filters, model) if filters else None
501
-
502
461
  # 기본 쿼리 생성
503
- query = await execute_query(
504
- session=session,
505
- model=model,
506
- explicit_joins=explicit_joins,
507
- loading_joins=loading_joins,
508
- conditions=conditions
509
- )
462
+ query = select(model)
463
+
464
+ # 명시적 조인 적용
465
+ if explicit_joins:
466
+ for join_target in explicit_joins:
467
+ if isinstance(join_target, tuple):
468
+ # (모델, 조인조건)이 전달된 경우
469
+ target_model, join_condition = join_target
470
+ query = query.outerjoin(target_model, join_condition)
471
+ else:
472
+ # 모델만 전달된 경우
473
+ query = query.outerjoin(join_target)
474
+
475
+ # 로딩 조인 적용
476
+ if loading_joins:
477
+ for join_option in loading_joins:
478
+ query = query.options(join_option)
479
+
480
+ # 필터 조건 적용
481
+ if filters:
482
+ conditions = build_conditions(filters, model)
483
+ query = query.where(and_(*conditions))
510
484
 
511
485
  # 정렬 조건 적용
512
486
  if order:
@@ -544,21 +518,48 @@ async def get_entity(
544
518
  explicit_joins: Optional[List[JoinTarget]] = None,
545
519
  loading_joins: Optional[List[Any]] = None
546
520
  ) -> ModelType:
521
+ """
522
+ 조건에 맞는 단일 엔티티를 조회합니다.
523
+
524
+ Args:
525
+ session: SQLAlchemy AsyncSession
526
+ model: SQLAlchemy 모델
527
+ conditions: 조회 조건
528
+ explicit_joins: 명시적 조인 대상 리스트
529
+ - 모델만 전달: 기본 outer join
530
+ - (모델, 조인조건): 조건부 outer join
531
+ loading_joins: 로딩 조인 옵션 리스트 (joinedload, selectinload 등)
532
+
533
+ Returns:
534
+ ModelType: 조회된 엔티티 또는 None
535
+ """
547
536
  try:
548
- # 조건을 리스트로 변환
549
- condition_list = [getattr(model, key) == value for key, value in conditions.items()]
550
-
551
- # 쿼리 실행
552
- query = await execute_query(
553
- session=session,
554
- model=model,
555
- explicit_joins=explicit_joins,
556
- loading_joins=loading_joins,
557
- conditions=condition_list
558
- )
537
+ # 기본 쿼리 생성
538
+ query = select(model)
539
+
540
+ # 명시적 조인 적용
541
+ if explicit_joins:
542
+ for join_target in explicit_joins:
543
+ if isinstance(join_target, tuple):
544
+ # (모델, 조인조건)이 전달된 경우
545
+ target_model, join_condition = join_target
546
+ query = query.outerjoin(target_model, join_condition)
547
+ else:
548
+ # 모델만 전달된 경우
549
+ query = query.outerjoin(join_target)
550
+
551
+ # 로딩 조인 적용
552
+ if loading_joins:
553
+ for join_option in loading_joins:
554
+ query = query.options(join_option)
555
+
556
+ # 조건 적용
557
+ if conditions:
558
+ for key, value in conditions.items():
559
+ query = query.where(getattr(model, key) == value)
559
560
 
560
561
  result = await session.execute(query)
561
- return result.scalars().unique().one_or_none()
562
+ return result.unique().scalars().one_or_none()
562
563
 
563
564
  except SQLAlchemyError as e:
564
565
  raise CustomException(
aiteamutils/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  """버전 정보"""
2
- __version__ = "0.2.163"
2
+ __version__ = "0.2.165"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiteamutils
3
- Version: 0.2.163
3
+ Version: 0.2.165
4
4
  Summary: AI Team Utilities
5
5
  Project-URL: Homepage, https://github.com/yourusername/aiteamutils
6
6
  Project-URL: Issues, https://github.com/yourusername/aiteamutils/issues
@@ -4,13 +4,13 @@ aiteamutils/base_repository.py,sha256=Oy2zE1i5qx60Xf1tnsaKLyFWapiPqt5JH8NejwNrPW
4
4
  aiteamutils/base_service.py,sha256=JIeRtFn1Ll4Qcq3v88pgS9lmEQLQoVyyOKqYR8n02S4,21192
5
5
  aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
6
6
  aiteamutils/config.py,sha256=YdalpJb70-txhGJAS4aaKglEZAFVWgfzw5BXSWpkUz4,3232
7
- aiteamutils/database.py,sha256=zXYhdUVgAisz4BuXZPPbvVLZ9lwRe7aVQP8J1AVE88Y,21771
7
+ aiteamutils/database.py,sha256=090b9M3o3nYsckVlfybC5LV7wUXS6n0Pve2yDOF_Y48,21669
8
8
  aiteamutils/enums.py,sha256=7WLqlcJqQWtETAga2WAxNp3dJTQIAd2TW-4WzkoHHa8,2498
9
9
  aiteamutils/exceptions.py,sha256=sgIVulllKMM9InTltaB7VD6i7DiQvCoycexsV-BiIBY,16570
10
10
  aiteamutils/files.py,sha256=fxnCu9rErd4vCovMi0jy4adLUiA7rx_q4RdOL4wSgsU,14258
11
11
  aiteamutils/security.py,sha256=McUl3t5Z5SyUDVUHymHdDkYyF4YSeg4g9fFMML4W6Kw,11630
12
12
  aiteamutils/validators.py,sha256=_WHN6jqJQzKM5uPTg-Da8U2qqevS84XeKMkCCF4C_lY,9591
13
- aiteamutils/version.py,sha256=MbP3Sxzx6eYugMlpPFw2qfjDxYmMdJwa_4K4MStAl1s,43
14
- aiteamutils-0.2.163.dist-info/METADATA,sha256=pgSEMmDcvxJrKq3Y-CmLEuXgd2K5vKvm8SQfa3jIuvA,1743
15
- aiteamutils-0.2.163.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- aiteamutils-0.2.163.dist-info/RECORD,,
13
+ aiteamutils/version.py,sha256=TC_spO53XsoBjGPdVSQjcP1vTh3Fno23EerP6g6nB58,43
14
+ aiteamutils-0.2.165.dist-info/METADATA,sha256=lRRin2H5r_RB8ha8ciB7hZo4fl-2M1C-L-c9V7SwOXA,1743
15
+ aiteamutils-0.2.165.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ aiteamutils-0.2.165.dist-info/RECORD,,