5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RuruCun個人開発Advent Calendar 2023

Day 22

Drizzle+SQLiteの初歩的な使い方メモ

Posted at

D1(SQLite)でDrizzleを使いだしてちょこちょこ調べることが必要になった項目のメモ
筆者はSQLiteを使いこんだことがないので、初歩的なことが多いです。

Schema周り

AutoIncrement

SQLiteでは列がInteger型かつPrimaryKeyの場合に設定できる。
integerからprimaryKeyを生やし、中にautoIncrementをtrueとすることで設定できる。

	id: integer('id').primaryKey({ autoIncrement: true }),

Boolean

SQLiteにboolean型がないので、整数型を指定し、modeにbooleanを設定します。
結果 0 or 1 で判断するようになります。

import { integer, sqliteTable } from "drizzle-orm/sqlite-core";
const table = sqliteTable('table', {
  id: integer('id', { mode: 'boolean' })
});

Date型

Booleanと同じく、SQLiteではない型なので、textに保存する。
created_atなど、カラムを追加した日付を入れたい場合は、default(sqlcurrent_date)などを使用する。

const table = sqliteTable("table", {
  time: text("time").default(sql`CURRENT_TIME`),
  date: text("date").default(sql`CURRENT_DATE`),
  timestamp: text("timestamp").default(sql`CURRENT_TIMESTAMP`),
});

Query周り

Select

全件取得するSELECT

const result = await db.select().from(users);

部分的なSELECT

selectにobjectとして渡すことで部分選択ができる。
SQLと同様に、任意の式を使用できる(lowerName)

const result = await db.select({
  field1: users.id,
  lowerName: sql<string>`lower(${users.name})`,
}).from(users);
const { field1, field2 } = result[0];

動的条件付きのSELECT

SELECT部分で、三項演算子を利用できる。
下記では、withNameで名前を返すかどうかを選択できる。

async function selectUsers(withName: boolean) {
  return db
    .select({
      id: users.id,
      ...(withName ? { name: users.name } : {}),
    })
    .from(users);
}

WHERE

Where

フィルター演算子を利用して、クエリをフィルタリングできる。

import { eq, lt, gte, ne } from 'drizzle-orm';
await db.select().from(users).where(eq(users.id, 42));
await db.select().from(users).where(lt(users.id, 42));
await db.select().from(users).where(gte(users.id, 42));
await db.select().from(users).where(ne(users.id, 42));
...
select "id", "name", "age" from "users" where "id" = 42;
select "id", "name", "age" from "users" where "id" < 42;
select "id", "name", "age" from "users" where "id" >= 42;
select "id", "name", "age" from "users" where "id" <> 42;

WHEREでのAND OR

and() or()内で、フィルター演算子を組み合わせて、実現できます。

import { eq, and, sql } from 'drizzle-orm';

await db.select().from(users).where(
  and(
    eq(users.id, 42),
    eq(users.name, 'Dan')
  )
);

その他でよく使うWHERE系のSQLは、直感的に使えるイメージでした。 .orderBy() count("*")など。

INSERT

INSERT時にコンフリクトした場合の処理

onConflictDoNothing()をつけることで、重複している場合は、スルーします。

await db.insert(users)
  .values({ id: 1, name: 'John' })
  .onConflictDoNothing();

重複した場合に、Upsertする場合は、onConflictDoUpdateをつけて、中身にtargetとsetを指定します。

await db.insert(users)
  .values({ id: 1, name: 'Dan' })
  .onConflictDoUpdate({ target: users.id, set: { name: 'John' } });
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?