Drizzle HTTP 代理

本指南假定您已熟悉:

HTTP 代理的工作方式以及你为什么可能需要它

当你需要实现自己的驱动程序与数据库之间的通信时,会使用 Drizzle Proxy。
它可以用于多种场景,例如在查询阶段结合现有驱动添加自定义逻辑。
最常见的用途是配合 HTTP 驱动:它将查询发送到你的服务器,由服务器连接数据库、执行查询,
并返回原始数据,然后由 Drizzle ORM 将其映射为结果。

底层是如何工作的?

┌───────────────────────────┐                 ┌─────────────────────────────┐              
│       Drizzle ORM         │                 │       带数据库的 HTTP 服务器    │             
└─┬─────────────────────────┘                 └─────────────────────────┬───┘             
  │                                                ^                    │
  │-- 1. 构建查询        2. 发送已构建的查询 --│                    │
  │                                                │                    │
  │              ┌───────────────────────────┐     │                    │
  └─────────────>│                           │─────┘                    │ 
                 │      HTTP 代理驱动         │                          │
  ┌──────────────│                           │<─────────────┬───────────┘
  │              └───────────────────────────┘              │
  │                                                  3. 执行查询 + 返回原始结果
  │-- 4. 映射数据并返回        

  v

Drizzle ORM 也支持直接使用异步回调函数来执行 SQL。

Drizzle 始终等待返回值为 {rows: string[][]}{rows: string[]}


// 驱动实现示例
import { drizzle } from 'drizzle-orm/pg-proxy';
import axios from "axios";

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: 'Unknown method value' });
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});