42 lines
1.9 KiB
Python
42 lines
1.9 KiB
Python
from sqlalchemy import select
|
||
from sqlalchemy.dialects.postgresql import insert as pg_insert
|
||
|
||
from common.database.db_session_manager import DB_SESSION_MNG
|
||
from common.database.model.models import place_itineraries
|
||
from common.utils.gtime import GTime
|
||
|
||
|
||
class PlaceItineraryCRUD:
|
||
async def list_by_place(self, db, place_id):
|
||
"""업장의 일정 전부(기간별 한 행). 정렬은 기간 이름 순이 아니라 저장 순이 아니다 —
|
||
화면 탭 순서는 읽는 쪽(`snapshot._local_contents`)이 DURATIONS 순으로 정한다."""
|
||
return await DB_SESSION_MNG.execute(
|
||
db,
|
||
select(place_itineraries).where(
|
||
place_itineraries.place_id == place_id,
|
||
place_itineraries.deleted == False, # noqa: E712
|
||
),
|
||
)
|
||
|
||
async def upsert(self, db, values: dict):
|
||
"""업장 × 기간 한 행의 삽입/갱신.
|
||
|
||
★ `uq_place_itineraries`(place_id, duration — deleted = false)에 태운다.
|
||
ON CONFLICT 술어는 인덱스 술어와 **글자 그대로** 같아야 한다. 아니면 포스트그레스가
|
||
"no unique or exclusion constraint matching" 으로 거절한다 — 표도 컬럼도 멀쩡해서
|
||
눈으로는 원인이 안 보인다(`local_content_crud.upsert_kind` 주석과 같은 함정).
|
||
"""
|
||
stmt = pg_insert(place_itineraries).values(**values)
|
||
stmt = stmt.on_conflict_do_update(
|
||
index_elements=[place_itineraries.place_id, place_itineraries.duration],
|
||
index_where=(place_itineraries.deleted == False), # noqa: E712
|
||
set_={
|
||
"body": stmt.excluded.body,
|
||
"generated_by": stmt.excluded.generated_by,
|
||
"model": stmt.excluded.model,
|
||
"generated_at": stmt.excluded.generated_at,
|
||
"updated_at": GTime.UTC(),
|
||
},
|
||
)
|
||
return await DB_SESSION_MNG.add(db, stmt)
|