aiteamutils 0.2.164__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
@@ -8,10 +8,11 @@ from typing import (
|
|
8
8
|
List,
|
9
9
|
Optional,
|
10
10
|
AsyncGenerator,
|
11
|
-
Union
|
11
|
+
Union,
|
12
|
+
Tuple
|
12
13
|
)
|
13
14
|
from sqlalchemy.ext.asyncio import AsyncSession
|
14
|
-
from sqlalchemy import select, and_, or_
|
15
|
+
from sqlalchemy import select, and_, or_, join
|
15
16
|
from sqlalchemy.orm import DeclarativeBase, joinedload, selectinload, contains_eager
|
16
17
|
from sqlalchemy.exc import SQLAlchemyError
|
17
18
|
from datetime import datetime
|
@@ -20,12 +21,18 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
20
21
|
from fastapi import Request
|
21
22
|
from ulid import ULID
|
22
23
|
from sqlalchemy import MetaData, Table, insert
|
24
|
+
from sqlalchemy.sql.elements import BinaryExpression
|
23
25
|
|
24
26
|
#패키지 라이브러리
|
25
27
|
from .exceptions import ErrorCode, CustomException
|
26
28
|
|
27
29
|
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
28
30
|
|
31
|
+
JoinTarget = Union[
|
32
|
+
DeclarativeBase, # 모델
|
33
|
+
Tuple[DeclarativeBase, BinaryExpression] # (모델, 조인 조건)
|
34
|
+
]
|
35
|
+
|
29
36
|
##################
|
30
37
|
# 전처리 #
|
31
38
|
##################
|
@@ -428,7 +435,7 @@ async def list_entities(
|
|
428
435
|
skip: int = 0,
|
429
436
|
limit: int = 100,
|
430
437
|
filters: Optional[List[Dict[str, Any]]] = None,
|
431
|
-
explicit_joins: Optional[List[
|
438
|
+
explicit_joins: Optional[List[JoinTarget]] = None,
|
432
439
|
loading_joins: Optional[List[Any]] = None,
|
433
440
|
order: Optional[List[Dict[str, str]]] = None
|
434
441
|
) -> List[Dict[str, Any]]:
|
@@ -441,31 +448,34 @@ async def list_entities(
|
|
441
448
|
skip: 페이지네이션 시작 위치.
|
442
449
|
limit: 페이지네이션 크기.
|
443
450
|
filters: 필터 조건 딕셔너리.
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
}
|
450
|
-
|
451
|
-
joins: 조인 옵션.
|
452
|
-
예시:
|
453
|
-
joins = [
|
454
|
-
selectinload(YourModel.related_field), # 관련된 필드를 함께 로드
|
455
|
-
joinedload(YourModel.another_related_field) # 다른 관계된 필드를 조인
|
456
|
-
]
|
451
|
+
explicit_joins: 명시적 조인 대상 리스트
|
452
|
+
- 모델만 전달: 기본 outer join
|
453
|
+
- (모델, 조인조건): 조건부 outer join
|
454
|
+
loading_joins: 로딩 조인 옵션 리스트 (joinedload, selectinload 등)
|
455
|
+
order: 정렬 조건 리스트
|
457
456
|
|
458
457
|
Returns:
|
459
458
|
List[Dict[str, Any]]: 쿼리 결과 리스트.
|
460
459
|
"""
|
461
460
|
try:
|
462
461
|
# 기본 쿼리 생성
|
462
|
+
query = select(model)
|
463
|
+
|
464
|
+
# 명시적 조인 적용
|
463
465
|
if explicit_joins:
|
464
|
-
query = select(model, *explicit_joins)
|
465
466
|
for join_target in explicit_joins:
|
466
|
-
|
467
|
-
|
468
|
-
|
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)
|
469
479
|
|
470
480
|
# 필터 조건 적용
|
471
481
|
if filters:
|
@@ -505,28 +515,51 @@ async def get_entity(
|
|
505
515
|
session: AsyncSession,
|
506
516
|
model: Type[ModelType],
|
507
517
|
conditions: Dict[str, Any],
|
508
|
-
explicit_joins: Optional[List[
|
518
|
+
explicit_joins: Optional[List[JoinTarget]] = None,
|
509
519
|
loading_joins: Optional[List[Any]] = None
|
510
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
|
+
"""
|
511
536
|
try:
|
537
|
+
# 기본 쿼리 생성
|
512
538
|
query = select(model)
|
513
539
|
|
514
540
|
# 명시적 조인 적용
|
515
541
|
if explicit_joins:
|
516
542
|
for join_target in explicit_joins:
|
517
|
-
|
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)
|
518
550
|
|
519
|
-
# 조인
|
551
|
+
# 로딩 조인 적용
|
520
552
|
if loading_joins:
|
521
553
|
for join_option in loading_joins:
|
522
554
|
query = query.options(join_option)
|
523
555
|
|
556
|
+
# 조건 적용
|
524
557
|
if conditions:
|
525
558
|
for key, value in conditions.items():
|
526
559
|
query = query.where(getattr(model, key) == value)
|
527
560
|
|
528
561
|
result = await session.execute(query)
|
529
|
-
return result.
|
562
|
+
return result.unique().scalars().one_or_none()
|
530
563
|
|
531
564
|
except SQLAlchemyError as e:
|
532
565
|
raise CustomException(
|
aiteamutils/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""버전 정보"""
|
2
|
-
__version__ = "0.2.
|
2
|
+
__version__ = "0.2.165"
|
@@ -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=
|
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
|
14
|
-
aiteamutils-0.2.
|
15
|
-
aiteamutils-0.2.
|
16
|
-
aiteamutils-0.2.
|
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,,
|
File without changes
|