Turso

根据其 官方网站 描述,Turso 是一个以 libSQL 为驱动的边缘 SQLite 数据库作为服务。

Drizzle ORM 原生支持 libSQL 驱动程序,我们采用 SQL 方言和方言特定的驱动程序和语法,并模拟最流行的类似 SQLite 的 allgetvaluesrun 查询方法的语法。

npm
yarn
pnpm
bun
npm i drizzle-orm @libsql/client
npm i -D drizzle-kit
import { drizzle } from 'drizzle-orm/libsql';
import { createClient } from '@libsql/client';

const client = createClient({ url: 'DATABASE_URL', authToken: 'DATABASE_AUTH_TOKEN' });

const db = drizzle(client);

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

除非您打算手动编写每个 SQL 查询,否则表声明非常有用:

import { sql } from "drizzle-orm";
import { text, integer, sqliteTable } from "drizzle-orm/sqlite-core";

const users = sqliteTable('users', {
  id: text('id'),
  textModifiers: text('text_modifiers').notNull().default(sql`CURRENT_TIMESTAMP`),
  intModifiers: integer('int_modifiers', { mode: 'boolean' }).notNull().default(false),
});

有关列类型的更多详细信息,请参阅 Drizzle 中的 SQLite 列类型

Cloudflare D1

根据其 官方网站 描述,D1 是 Cloudflare 的第一个可查询关系数据库。

Drizzle ORM 完全支持 Cloudflare D1 数据库和 Cloudflare Workers 环境。 我们采用 SQL 方言和方言特定的驱动程序和语法,并模拟最流行的类似 SQLite 的 allgetvaluesrun 查询方法的语法。

要为您的 Cloudflare D1 设置项目,请参阅 官方文档

### your wrangler.toml will look something like this:

name = "YOUR PROJECT NAME"
main = "src/index.ts"
compatibility_date = "2022-11-07"
node_compat = true

[[ d1_databases ]]
binding = "DB"
database_name = "YOUR DB NAME"
database_id = "YOUR DB ID"
migrations_dir = "drizzle/migrations"

初始化本地数据库并在本地运行服务器:

wrangler d1 migrations apply <DATABASE_NAME> --local
wrangler dev ## 在版本低于 3.0.0 的 wrangler 加上 --local 和 --persist 标志

安装 Drizzle ORM:

npm
yarn
pnpm
bun
npm i drizzle-orm
npm i -D drizzle-kit

进行第一个 D1 查询:

import { drizzle } from 'drizzle-orm/d1';

export interface Env {
  <BINDING_NAME>: D1Database;
}

export default {
  async fetch(request: Request, env: Env) {
    const db = drizzle(env.<BINDING_NAME>);
    const result = await db.select().from(users).all()
    return Response.json(result);
  },
};

除非您打算手动编写每个 SQL 查询,否则表声明非常有用:

import { sql } from "drizzle-orm";
import { text, integer, sqliteTable } from "drizzle-orm/sqlite-core";

const users = sqliteTable('users', {
  id: text('id'),
  textModifiers: text('text_modifiers').notNull().default(sql`CURRENT_TIMESTAMP`),
  intModifiers: integer('int_modifiers', { mode: 'boolean' }).notNull().default(false),
});

有关列类型的更多详细信息,请参阅 Drizzle 中的 SQLite 列类型

Bun SQLite

根据其 官方网站 描述,Bun 是一个快速的全能的 JavaScript 运行时。

Drizzle ORM 原生支持 bun:sqlite 模块,而且速度非常快 🚀

我们采用 SQL 方言和方言特定的驱动程序和语法,并与其他任何 ORM 不同, 对于像是 bun:sqlite 这样的同步驱动程序,我们同时具有 asyncsync API,并且我们模拟了最流行的类似 SQLite 的 allgetvaluesrun 查询方法的语法。

npm
yarn
pnpm
bun
npm i drizzle-orm
npm i -D drizzle-kit
import { drizzle } from 'drizzle-orm/bun-sqlite';
import { Database } from 'bun:sqlite';

const sqlite = new Database('sqlite.db');
const db = drizzle(sqlite);

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

除非您打算手动编写每个 SQL 查询,否则表声明非常有用:

import { sql } from "drizzle-orm";
import { text, integer, sqliteTable } from "drizzle-orm/sqlite-core";

const users = sqliteTable('users', {
  id: text('id'),
  textModifiers: text('text_modifiers').notNull().default(sql`CURRENT_TIMESTAMP`),
  intModifiers: integer('int_modifiers', { mode: 'boolean' }).notNull().default(false),
});

有关列类型的更多详细信息,请参阅 Drizzle 中的 SQLite 列类型

如果要使用 sync API:

import { drizzle } from 'drizzle-orm/bun-sqlite';
import { Database } from 'bun:sqlite';

const sqlite = new Database('sqlite.db');
const db = drizzle(sqlite);

const result = db.select().from(users).all();
const result = db.select().from(users).get();
const result = db.select().from(users).values();
const result = db.select().from(users).run();

有关 sqlite 的 syncasync API 的更多信息 - 请阅读此处。

Expo SQLite

根据其 官方网站 描述,Expo 是基于 React Native 开发、构建和发布应用程序的工具生态系统。 它由 Hermes JavaScript 运行时和 Metro bundler 提供动力,Drizzle Expo 驱动程序旨在原生支持这两者。

Drizzle ORM 在 Expo SQLite 中拥有最佳的工具包:

  • Expo SQLite 的原生 ORM 驱动程序 ✅
  • Drizzle Kit 支持应用程序中的迁移生成和捆绑 ✅
  • Drizzle Studio 开发工具插件,用于浏览设备数据库 ✅
  • 实时查询 ✅
npm
yarn
pnpm
bun
npm i drizzle-orm expo-sqlite@next
npm i -D drizzle-kit
import { drizzle } from "drizzle-orm/expo-sqlite";
import { openDatabaseSync } from "expo-sqlite/next";

const expo = openDatabaseSync("db.db");
const db = drizzle(expo);

await db.select().from(users);

实时查询

使用 useLiveQuery 钩子,您可以使任何 Drizzle 查询具有响应性:

import { useLiveQuery, drizzle } from 'drizzle-orm/expo-sqlite';
import { openDatabaseSync } from 'expo-sqlite/next';
import { Text } from 'react-native';
import * as schema from './schema';

const expo = openDatabaseSync('db.db', { enableChangeListener: true }); // <-- enable change listeners
const db = drizzle(expo);

const App = () => {
  // 数据更改时会自动重新渲染
  const { data } = useLiveQuery(db.select().from(schema.users));
  return <Text>{JSON.stringify(data)}</Text>;
};

export default App;

使用 Drizzle Kit 进行 Expo SQLite 迁移

您可以使用 Drizzle Kit 生成 SQL 迁移。在进行下一步之前,请确保查看 Drizzle Kit 迁移 的工作原理。 Expo / React Native 要求您将 SQL 迁移捆绑到应用程序中,我们已为您提供覆盖。

安装 babel 插件

必须直接将 SQL 迁移文件作为字符串捆绑到您的包中。

npm install babel-plugin-inline-import

更新配置文件

您需要更新 babel.config.jsmetro.config.jsdrizzle.config.ts 文件

babel.config.js
module.exports = function(api) {
  api.cache(true);

  return {
    presets: ['babel-preset-expo'],
    plugins: [["inline-import", { "extensions": [".sql"] }]] // <-- add this
  };
};
metro.config.js
const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.sourceExts.push('sql'); // <--- add this

module.exports = config;

确保在 Drizzle Kit 配置中拥有 dialect: 'sqlite'driver: 'expo'

drizzle.config.ts
import type { Config } from 'drizzle-kit';

export default {
  schema: './db/schema.ts',
  out: './drizzle',
  dialect: 'sqlite',
  driver: 'expo', // <--- very important
} satisfies Config;

生成迁移

在创建 SQL 模式文件和 drizzle.config.ts 文件之后,您可以生成迁移

npx drizzle-kit generate

添加迁移到您的应用程序

现在需要从 ./drizzle 文件夹导入 migrations.js 文件到 Expo/React Native 应用程序中。 您可以在应用程序启动时使用我们的自定义 useMigrations 迁移钩子运行迁移,也可以在 useEffect 钩子中手动运行。

App.tsx
import { drizzle } from "drizzle-orm/expo-sqlite";
import { openDatabaseSync } from "expo-sqlite/next";
import { useMigrations } from 'drizzle-orm/expo-sqlite/migrator';
import migrations from './drizzle/migrations';

const expoDb = openDatabaseSync("db.db");

const db = drizzle(expoDb);

export default function App() {
  const { success, error } = useMigrations(db, migrations);

  if (error) {
    return (
      <View>
        <Text>Migration error: {error.message}</Text>
      </View>
    );
  }

  if (!success) {
    return (
      <View>
        <Text>Migration is in progress...</Text>
      </View>
    );
  }

  return ...your application component;
}

OP SQLite

根据其 官方网站 描述,OP-SQLite 嵌入了最新版本的 SQLite,并提供了一个执行 SQL 查询的低级 API。

npm
yarn
pnpm
bun
npm i drizzle-orm @op-engineering/op-sqlite
npm i -D drizzle-kit
import { drizzle } from "drizzle-orm/op-sqlite";
import { open } from '@op-engineering/op-sqlite';

const opsqlite = open({
  name: 'myDB',
});
const db = drizzle(opsqlite);

await db.select().from(users);

您可以使用 Drizzle Kit 生成 SQL 迁移。在进行下一步之前,请确保查看 Drizzle Kit 迁移 的工作原理。 OP SQLite 要求您将 SQL 迁移捆绑到应用程序中,我们已为您提供覆盖。

安装 babel 插件

必须直接将 SQL 迁移文件作为字符串捆绑到您的包中。

npm install babel-plugin-inline-import

更新配置文件

您需要更新 babel.config.jsmetro.config.jsdrizzle.config.ts 文件

babel.config.js
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    [
      'inline-import',
      {
        extensions: ['.sql'],
      },
    ],
  ],
};
metro.config.js
const { getDefaultConfig } = require('@react-native/metro-config');

const config = getDefaultConfig(__dirname);

config.resolver.sourceExts.push('sql');

module.exports = config;

确保在 Drizzle Kit 配置中拥有 dialect: 'sqlite'driver: 'expo'

drizzle.config.ts
import type { Config } from 'drizzle-kit';

export default {
  schema: './db/schema.ts',
  out: './drizzle',
  dialect: 'sqlite',
  driver: 'expo', // <--- very important
} satisfies Config;

生成迁移

在创建 SQL 模式文件和 drizzle.config.ts 文件之后,您可以生成迁移

npx drizzle-kit generate

添加迁移到您的应用程序

现在需要从 ./drizzle 文件夹导入 migrations.js 文件到 Expo/React Native 应用程序中。 您可以在应用程序启动时使用我们的自定义 useMigrations 迁移钩子运行迁移,也可以在 useEffect 钩子中手动运行。

App.tsx
import { drizzle } from "drizzle-orm/op-sqlite";
import { open } from '@op-engineering/op-sqlite';
import { useMigrations } from 'drizzle-orm/op-sqlite/migrator';
import migrations from './drizzle/migrations';

const opsqliteDb = open({
  name: 'myDB',
});

const db = drizzle(opsqliteDb);

export default function App() {
  const { success, error } = useMigrations(db, migrations);

  if (error) {
    return (
      <View>
        <Text>Migration error: {error.message}</Text>
      </View>
    );
  }

  if (!success) {
    return (
      <View>
        <Text>Migration is in progress...</Text>
      </View>
    );
  }

  return ...your application component;
}

React Native SQLite

请使用 Expo SQLite 在 React Native 应用程序中运行 Drizzle ORM。 我们发现唯一的 流行库 不支持新的 Hermes JavaScript 运行时, 而新的 Hermes JavaScript 运行时现在是 React Native 和 Expo 的开箱即用标准运行时。

better-sqlite3

根据其 官方网站 描述,BetterSqlite3 是 Node.js 中最快、最简单的 SQLite3 库。

Drizzle ORM 采用 SQL 方言和方言特定的驱动程序和语法,并且与任何其他 ORM 不同, 对于像是 better-sqlite3 这样的同步驱动程序,我们同时具有 asyncsync API,并且我们模拟了最流行的类似 SQLite 的 allgetvaluesrun 查询方法的语法。

npm
yarn
pnpm
bun
npm i drizzle-orm better-sqlite3
npm i -D drizzle-kit
import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';

const sqlite = new Database('sqlite.db');
const db = drizzle(sqlite);

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

除非您打算手动编写每个 SQL 查询,否则表声明非常有用:

import { sql } from "drizzle-orm";
import { text, integer, sqliteTable } from "drizzle-orm/sqlite-core";

const users = sqliteTable('users', {
  id: text('id'),
  textModifiers: text('text_modifiers').notNull().default(sql`CURRENT_TIMESTAMP`),
  intModifiers: integer('int_modifiers', { mode: 'boolean' }).notNull().default(false),
});

有关列类型的更多详细信息,请参阅 Drizzle 中的 SQLite 列类型

ℹ️

如果您的 db.insert() 返回数据,请在查询中添加 all(),否则添加 run()

如果要使用 sync API:

import { drizzle, BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';

const sqlite = new Database('sqlite.db');
const db: BetterSQLite3Database = drizzle(sqlite);

const result = db.select().from(users).all();
const result = db.select().from(users).get();
const result = db.select().from(users).values();
const result = db.select().from(users).run();

有关 sqlite 的 syncasync API 的更多信息 - 请阅读此处。

HTTP 代理

Drizzle ORM 还支持使用异步回调函数进行执行 SQL。

  • sql 是带有占位符的查询字符串。

  • params 是参数的数组。

  • 根据 SQL 语句,method 的值将设为 runallvaluesget。 Drizzle 始终等待返回值为 {rows: string[][]}{rows: string[]}

  • methodget 时,您应该返回一个值为 {rows: string[]} 的对象。

  • 否则,您应返回 {rows: string[][]} 的对象。

import { drizzle } from 'drizzle-orm/sqlite-proxy';

const db = drizzle(async (sql, params, method) => {
  try {
    const rows = await axios.post('http://localhost:3000/query', { sql, params, method });

    return { rows: rows.data };
  } catch (e: any) {
    console.error('Error from sqlite proxy server: ', e.response.data)
    return { rows: [] };
  }
});

批量支持

Sqlite 代理支持批量请求,与所有其他驱动程序一样。查看完整的 文档

您需要为批量查询指定一个特定的回调函数,并处理对代理服务器的请求:

import { drizzle } from 'drizzle-orm/sqlite-proxy';

type ResponseType = { rows: any[][] | any[] }[];

const db = drizzle(async (sql, params, method) => {
  // single queries logic. Same as in code above
}, async (queries: { sql: string, params: any[], method: 'all' | 'run' | 'get' | 'values'}[]) => {
    try {
      const result: ResponseType = await axios.post('http://localhost:3000/batch', { queries });

      return result;
    } catch (e: any) {
      console.error('Error from sqlite proxy server:', e);
      throw e;
    }
  });

然后,您可以使用 db.batch([]) 方法,该方法将代理所有查询。

💡

批处理的响应应为原始值数组(数组内的数组),顺序与发送到代理服务器的顺序相同。


除非您打算手动编写每个 SQL 查询,否则表声明非常有用:

import { sql } from "drizzle-orm";
import { text, integer, sqliteTable } from "drizzle-orm/sqlite-core";

const users = sqliteTable('users', {
  id: text('id'),
  textModifiers: text('text_modifiers').notNull().default(sql`CURRENT_TIMESTAMP`),
  intModifiers: integer('int_modifiers', { mode: 'boolean' }).notNull().default(false),
});

有关列类型的更多详细信息,请参阅 Drizzle 中的 SQLite 列类型

Become a Gold Sponsor