Drizzle ORM은 데이터베이스 테이블에 행을 삽입하는 가장 SQL스러운 방법을 제공합니다.
행 하나 삽입하기
Drizzle을 사용해 데이터를 삽입하는 것은 매우 직관적이며 SQL과 유사합니다. 직접 확인해 보세요:
특정 테이블에 대한 삽입 타입이 필요하다면 typeof usersTable.$inferInsert 구문을 사용할 수 있습니다.
Insert returning
PostgreSQL
SQLite
MySQL
SingleStore
PostgreSQL과 SQLite에서는 행을 삽입하고 해당 행을 반환받을 수 있습니다. 다음과 같이 사용할 수 있습니다:
$returningId 삽입
PostgreSQL
SQLite
MySQL
SingleStore
MySQL은 INSERT 이후에 RETURNING을 기본적으로 지원하지 않습니다. autoincrement(또는 serial) 타입의 primary key에 대해서만 insertId와 affectedRows 필드를 통해 접근할 수 있습니다. Drizzle에서는 이러한 경우를 자동으로 처리하고, 삽입된 모든 ID를 별도의 객체로 반환하는 방법을 제공합니다.
또한 Drizzle에서는 $default 함수를 사용해 런타임에 커스텀 primary key를 생성할 수 있습니다. 이렇게 생성된 키도 $returningId() 호출 시 반환됩니다.
만약 primary key가 없다면, 해당 쿼리의 타입은 {}[]가 됩니다.
여러 행 삽입하기
위 코드는 데이터베이스에 여러 행을 한 번에 삽입하는 예제입니다. users 테이블에 name이 ‘Andrew’와 ‘Dan’인 두 개의 행을 추가합니다. values 메서드에 배열을 전달하여 여러 행을 동시에 삽입할 수 있습니다.
Upserts와 충돌 처리
Drizzle ORM은 Upserts와 충돌 처리를 위한 간단한 인터페이스를 제공합니다.
충돌 시 아무 작업도 하지 않음
PostgreSQL
SQLite
MySQL
SingleStore
onConflictDoNothing은 충돌이 발생할 경우 삽입 작업을 취소합니다:
충돌 시 업데이트하기
PostgreSQL
SQLite
MySQL
onConflictDoUpdate는 충돌이 발생할 경우 해당 행을 업데이트합니다:
where 절
on conflict do update 구문은 두 가지 위치에 where 절을 사용할 수 있습니다. 하나는 충돌 대상(예: 부분 인덱스)에 포함되는 경우이고, 다른 하나는 update 절에 포함되는 경우입니다.
Drizzle에서 이러한 조건을 지정하려면 setWhere와 targetWhere 절을 사용할 수 있습니다.
복합 인덱스 또는 복합 기본 키를 사용한 onConflictDoUpdate 업서트 예제입니다.
중복 키 업데이트
PostgreSQL
SQLite
MySQL
SingleStore
MySQL은 ON CONFLICT 절 대신 ON DUPLICATE KEY UPDATE를 지원합니다. MySQL은 기본 키와 고유 인덱스를 기반으로 충돌 대상을 자동으로 결정하며, 어떤 고유 인덱스가 충돌하더라도 해당 행을 업데이트합니다.
Drizzle는 onDuplicateKeyUpdate 메서드를 통해 이를 지원합니다:
MySQL은 충돌 시 아무 작업도 수행하지 않는 기능을 직접 지원하지 않지만, 특정 컬럼의 값을 자기 자신으로 설정하여 동일한 효과를 얻을 수 있습니다:
with 절을 사용하면 복잡한 쿼리를 더 작은 하위 쿼리로 나눌 수 있습니다. 이를 공통 테이블 표현식(CTE)이라고 합니다:
이 예제에서는 user_count라는 CTE를 정의하고, 이를 사용하여 users 테이블에 데이터를 삽입합니다. 삽입 시 admin 컬럼의 값은 user_count의 결과에 따라 결정됩니다. 마지막으로 삽입된 데이터의 admin 컬럼 값을 반환합니다.
INSERT INTO … SELECT
SQLite 문서에 따르면:
INSERT 문의 두 번째 형태는 VALUES 절 대신 SELECT 문을 포함합니다.
SELECT 문을 실행하여 반환된 각 행에 대해 테이블에 새로운 항목이 삽입됩니다.
열 목록이 지정된 경우, SELECT 결과의 열 수는 열 목록의 항목 수와 동일해야 합니다.
그렇지 않으면, 열 목록이 지정되지 않은 경우 SELECT 결과의 열 수는 테이블의 열 수와 동일해야 합니다.
ORDER BY 및/또는 LIMIT 절을 포함한 복합 SELECT 문을 포함한 모든 SELECT 문은 이 형태의 INSERT 문에서 사용할 수 있습니다.
IMPORTANT
파싱 모호성을 피하기 위해, SELECT 문은 WHERE 절을 항상 포함해야 합니다.
upsert-clause가 있는 경우, WHERE 절이 단순히 “WHERE true”라도 포함되어야 합니다.
WHERE 절이 없으면 파서가 “ON” 토큰이 SELECT의 조인 제약 조건인지, 아니면 upsert-clause의 시작인지 알 수 없습니다.
PostgreSQL 문서에 따르면:
삽입할 행을 제공하는 쿼리(SELECT 문)
MySQL 문서에 따르면:
INSERT … SELECT를 사용하면 SELECT 문의 결과로부터 테이블에 많은 행을 빠르게 삽입할 수 있습니다.
SELECT 문은 하나 이상의 테이블에서 선택할 수 있습니다.
Drizzle는 모든 SQL 방언에 대해 현재 구문을 지원하며, 모든 방언이 동일한 구문을 공유합니다.
일반적인 시나리오와 API 사용법을 살펴보겠습니다.
INSERT 문 내부에서 SELECT를 사용하는 여러 방법이 있으며, 여러분이 선호하는 방식을 선택할 수 있습니다: