Drizzle과 Expo 시작하기
This guide assumes familiarity with:
- Expo SQLite - SQLite API를 통해 쿼리할 수 있는 데이터베이스에 대한 액세스를 제공하는 라이브러리 - 자세히 보기
Step 1 - Expo 템플릿으로 프로젝트 설정
npm
yarn
pnpm
bun
npx create expo-app --template blank-typescript
이 템플릿에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
기본 파일 구조
템플릿을 설치하고 db 폴더를 추가하면 다음과 같은 구조가 생성됩니다. db/schema.ts 파일에는 Drizzle 테이블 정의가 포함되어 있으며, drizzle 폴더에는 SQL 마이그레이션 파일과 스냅샷이 포함됩니다.
📦 <project root>
├ 📂 assets
├ 📂 drizzle
├ 📂 db
│ └ 📜 schema.ts
├ 📜 .gitignore
├ 📜 .npmrc
├ 📜 app.json
├ 📜 App.tsx
├ 📜 babel.config.ts
├ 📜 drizzle.config.ts
├ 📜 package.json
└ 📜 tsconfig.jsonStep 2 - expo-sqlite 패키지 설치
npm
yarn
pnpm
bun
npx expo install expo-sqlite
Step 3 - 필수 패키지 설치
npm
yarn
pnpm
bun
npm i drizzle-orm
npm i -D drizzle-kit
Step 4 - 데이터베이스에 Drizzle ORM 연결
루트 디렉토리에 App.tsx 파일을 생성하고 연결을 초기화합니다:
import * as SQLite from 'expo-sqlite';
import { drizzle } from 'drizzle-orm/expo-sqlite';
const expo = SQLite.openDatabaseSync('db.db');
const db = drizzle(expo);Step 5 - 테이블 생성
db 디렉토리에 schema.ts 파일을 생성하고 테이블을 정의합니다:
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";
export const usersTable = sqliteTable("users_table", {
id: int().primaryKey({ autoIncrement: true }),
name: text().notNull(),
age: int().notNull(),
email: text().notNull().unique(),
});Step 6 - Drizzle 설정 파일 설정
Drizzle config - Drizzle Kit에서 사용되는 설정 파일로, 데이터베이스 연결, 마이그레이션 폴더 및 스키마 파일에 대한 모든 정보를 포함합니다.
프로젝트 루트에 drizzle.config.ts 파일을 생성하고 다음 내용을 추가합니다:
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
dialect: 'sqlite',
driver: 'expo',
schema: './db/schema.ts',
out: './drizzle',
});Step 7 - metro 설정
루트 폴더에 metro.config.js 파일을 생성하고 다음 코드를 추가합니다:
const { getDefaultConfig } = require('expo/metro-config');
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.sourceExts.push('sql');
module.exports = config;Step 8 - babel 설정 업데이트
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [["inline-import", { "extensions": [".sql"] }]] // <-- add this
};
};Step 9 - 데이터베이스에 변경사항 적용
Expo에서는 drizzle-kit generate 명령으로 마이그레이션을 생성한 다음, 런타임에 drizzle-orm의 migrate() 함수를 사용하여 적용해야 합니다.
마이그레이션 생성:
npx drizzle-kit generateStep 10 - 마이그레이션 적용 및 데이터베이스 쿼리
사용자를 생성, 조회, 업데이트 및 삭제하는 마이그레이션과 쿼리가 포함된 App.tsx 파일을 작성해봅시다.
import { Text, View } from 'react-native';
import * as SQLite from 'expo-sqlite';
import { useEffect, useState } from 'react';
import { drizzle } from 'drizzle-orm/expo-sqlite';
import { usersTable } from './db/schema';
import { useMigrations } from 'drizzle-orm/expo-sqlite/migrator';
import migrations from './drizzle/migrations';
const expo = SQLite.openDatabaseSync('db.db');
const db = drizzle(expo);
export default function App() {
const { success, error } = useMigrations(db, migrations);
const [items, setItems] = useState<typeof usersTable.$inferSelect[] | null>(null);
useEffect(() => {
if (!success) return;
(async () => {
await db.delete(usersTable);
await db.insert(usersTable).values([
{
name: 'John',
age: 30,
email: 'john@example.com',
},
]);
const users = await db.select().from(usersTable);
setItems(users);
})();
}, [success]);
if (error) {
return (
<View>
<Text>Migration error: {error.message}</Text>
</View>
);
}
if (!success) {
return (
<View>
<Text>Migration is in progress...</Text>
</View>
);
}
if (items === null || items.length === 0) {
return (
<View>
<Text>Empty</Text>
</View>
);
}
return (
<View
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
width: '100%',
height: '100%',
justifyContent: 'center',
}}
>
{items.map((item) => (
<Text key={item.id}>{item.email}</Text>
))}
</View>
);
}Step 11 - Expo 앱 프리빌드 및 실행
npm
yarn
pnpm
bun
npx expo run:ios