generate
migrate
push
pull
check
up
studio
HTTP 代理的工作原理以及您可能需要它的原因
Drizzle Proxy 在您需要实现自己的驱动程序与数据库的通信时使用。 它可以在几种情况下使用,例如在现有驱动程序的查询阶段添加自定义逻辑。 最常见的用法是与 HTTP 驱动程序一起使用,它将查询发送到您的数据库服务器,执行查询 并以原始数据响应,Drizzle ORM 然后可以将其映射为结果。
它是如何在底层工作的?
┌───────────────────────────┐ ┌─────────────────────────────┐ │ Drizzle ORM │ │ 带数据库的 HTTP 服务器 │ └─┬─────────────────────────┘ └─────────────────────────┬───┘ │ ^ │ │-- 1. 构建查询 2. 发送构建的查询 --│ │ │ │ │ │ ┌───────────────────────────┐ │ │ └─────────────>│ │─────┘ │ │ HTTP 代理驱动 │ │ ┌──────────────│ │<─────────────┬───────────┘ │ └───────────────────────────┘ │ │ 3. 执行查询 + 返回原始结果 │-- 4. 映射数据并返回 │ v
Drizzle ORM 还支持简单地使用异步回调函数来执行 SQL。
sql
params
method
run
all
values
get
Drizzle 总是等待返回值为 {rows: string[][]} 或 {rows: string[]}。
{rows: string[][]}
{rows: string[]}
// 驱动程序实现示例 import { drizzle } from 'drizzle-orm/pg-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('来自 pg 代理服务器的错误:', e.response.data) return { rows: [] }; } });
// 服务器实现示例 import { Client } from 'pg'; import express from 'express'; const app = express(); app.use(express.json()); const port = 3000; const client = new Client('postgres://postgres:postgres@localhost:5432/postgres'); app.post('/query', async (req, res) => { const { sql, params, method } = req.body; // 防止多次查询 const sqlBody = sql.replace(/;/g, ''); try { const result = await client.query({ text: sqlBody, values: params, rowMode: method === 'all' ? 'array' : undefined, }); res.send(result.rows); } catch (e: any) { res.status(500).json({ error: e }); } res.status(500).json({ error: '未知的方法值' }); }); app.listen(port, () => { console.log(`示例应用监听在端口 ${port}`); });
// 驱动程序实现示例 import { drizzle } from 'drizzle-orm/mysql-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('来自 mysql 代理服务器的错误:', e.response.data) return { rows: [] }; } });
// 服务器实现示例 import * as mysql from 'mysql2/promise'; import express from 'express'; const app = express(); app.use(express.json()); const port = 3000; const main = async () => { const connection = await mysql.createConnection('mysql://root:mysql@127.0.0.1:5432/drizzle'); app.post('/query', async (req, res) => { const { sql, params, method } = req.body; // 防止多次查询 const sqlBody = sql.replace(/;/g, ''); try { const result = await connection.query({ sql: sqlBody, values: params, rowsAsArray: method === 'all', typeCast: function(field: any, next: any) { if (field.type === 'TIMESTAMP' || field.type === 'DATETIME' || field.type === 'DATE') { return field.string(); } return next(); }, }); } catch (e: any) { res.status(500).json({ error: e }); } if (method === 'all') { res.send(result[0]); } else if (method === 'execute') { res.send(result); } res.status(500).json({ error: '未知的方法值' }); }); app.listen(port, () => { console.log(`示例应用监听在端口 ${port}`); }); } main();
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('来自 sqlite 代理服务器的错误:', e.response.data) return { rows: [] }; } });
批量支持
Sqlite Proxy 支持批量请求,和其他驱动程序的处理方式相同。请查看完整的 文档
您需要为批量查询指定特定的回调,并处理对代理服务器的请求:
import { drizzle } from 'drizzle-orm/sqlite-proxy'; type ResponseType = { rows: any[][] | any[] }[]; const db = drizzle(async (sql, params, method) => { // 单查询逻辑。和上面的代码相同 }, 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('来自 sqlite 代理服务器的错误:', e); throw e; } });
然后您可以使用 db.batch([]) 方法,这将代理所有查询。
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), });
有关列类型的更多详细信息,请参见 SQLite 中的列类型在 Drizzle.