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 =
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
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
|
-
|
550
|
-
|
551
|
-
#
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
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.
|
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.
|
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
|