Server/DB

Prisma) QueryBuilder, RawQuery and SQL-Teamplate-String

Juzdalua 2022. 4. 15. 15:55

쿼리빌더의 한계

Prisma의 쿼리빌더를 사용하다보니 제약이 엄청나게 많았다.

문제는 String type의 컬럼을 natural sort를 할 수 없는 것에서 시작했다.

1, 11, 2, 25, 3, .... 8999, 9

 

쿼리문에서는 다음처럼 해결한다.

ORDER BY ID+0 ASC

 

ID 기반 페이지네이션이나 매핑기능, 가독성 등 쿼리빌더의 활용성은 많았지만 안타깝게도 PostgreSQL에 한정되어 더 많은 신기술을 제공하고 있었다.

MySQL 기반 작업을 하는 나로써는 매우 안타까웠다.

 

로우쿼리의 한계

JS에서 변수로 쿼리를 조회해야 할 때, 조건문이 필요하다.

Prisma.$queryRaw에서는 변수와 조건문을 제공하지만 가독성이 떨어지고 정해진 룰에 맞춰야만 한다.

Prisma.$queryRaw`
SELECT * FROM USERS 
${query.id ? Prisma.Sql`WHERE ID = ${query.id}` : Prisma.empty}
`

 

문제는 반복문이 먹지 않는다. forEach로 들어가는 순간 에러를 뱉는데, 원인을 찾지 못했다.

그래서 선택한 SQL-Template-String.

Prisma에서는 해당 템플릿을 매핑해서 코드를 구성했다고 한다.

 

SQL 템플릿

https://www.npmjs.com/package/sql-template-strings

깃허브에 다양한 사용법이 있었다.

import { Sql } from '@prisma/client/runtime';
import SQL from "sql-template-strings";

// Start Query
const findQuery = SQL`SELECT * FROM USERS WHERE ( ADDRESS = ${address}`;

// Exist Keword
if( query.keyword )
    findQuery.append(SQL` AND ( NAME LIKE ${`%${query.keyword}%`} OR TOKEN_ID LIKE ${`%${query.keyword}%`} )`);

// Close WHERE clause
findQuery.append(SQL`)`);

// Add sort
if( !query.sort )
	findQuery.append(SQL` ORDER BY ISNULL(LAST_SALE_PRICE), TOKEN_ID+0 ASC`);
    
const response: [] = await this.$queryRaw`${new Sql(findQuery['strings'], findQuery['values'])}`

 

템플릿은 [strings, sql, value]의 값을 가진다. 

SQL-Template-String을 활용해서 쿼리를 생성하고 Prisma query에 적용시키는 방법이다.

조건식이 복잡하다면 reduce() 함수를 활용하여 append 할 수 있다.

다양한 방법을 알려주신 CTO님께 감사를...!!