query() 내 컬럼 정의시 인자 값 alias 설정

정규환·2022년 9월 1일
0

python Back-End 개발을 시작한지 얼마되지 않아,
소스 내 ORM 코드 개선 작업을 하게되었다.

기존 코드는 execute() 의 파라미터에 DB쿼리의 문자열 변수로 select 조회하는 방식이였는데,
이전 직장에서 .Core 환경에서의 EF(Entity Framework) 코드 짜던 버릇으로
개선하기로 마음먹고 수정작업을 진행했었는데, 그 중 시행착오를 겪었던 부분을 이렇게 블로그에 남기면 좋을 것 같아 글을 게시해본다.

일단 내가 원하는 sql query 문과 swagger GET api 호출 결과는 아래와 같다.

select 1111 as 'seq',
       avg(or.result_values[1]) * 100 as 'positive'
       avg(or.result_values[2]) * 100 as 'negative'
       avg(or.result_values[3]) * 100 as 'nomal'
  from obaervation_info as oi
       join observation_result as or on oi.id = or.observation_info_id
 where oi.seq = 1111
   and or.observation_time > 600
   and or.isValidDataRow = 1       
{
	"seq":1111,
    "positive":null,
    "negative":null,
    "nomal":null
}

시행착오는 겪었던 부분은 바로 맨 윗부분이다.

select 1111 as 'seq',

1111 은 함수호출시의 인자 값이다.
아래 코드는 해결되기 전의 기존 python ORM 코드이다.

def get_observiation_no_result(no):
  try:
    return db.session.query(
      ObservationInfo.seq.label('seq'),
      (func.avg(ObservationResult.result_value[1])*100).label('positive'),
      (func.avg(ObservationResult.result_value[1])*100).label('positive'))\
      .select_from(ObservationInfo)
      .join(ObservationResult, ObservationInfo.id == ObservationResult.observation_info_id)\
      .filter(
      and_(oi.seq == no,
           or.observation_time > 600
           or.isValidDataRow = 1)
      ).first()
  exception Exception as e:
    print(e)
  finally:
    db.session.close()            

위의 코드에서 문제점은 조건절에 조회되는 데이타가 없을 경우
원하는 json 결과로 리턴되지 않는다는 것이다.
(http Status Code 204 로 리턴)

따라서 조건절에 조회되는 데이타가 없더라도
'seq' 에는 인자값이 들어간 리턴을 받고 싶기때문에 해결책으로 cast() 를 활용하는 방법을 생각했다.

def get_observiation_no_result(no):
  try:
  ...
      func.cast(no, Integer).label('seq'),
  ...
  finally:
    db.session.close()   

포스팅이 처음이라 읽기 난잡할 수 있을 것 같은데,
비슷한 고민을 하는 개발자에게 힌트가 되었으면 한다.

만약 더 좋은 해결책이 있으면 공유받았으면 좋겠다.

0개의 댓글