# @drizzle-adapter/node-postgres 中文文档

规范地址：https://npmcn.com/package/%40drizzle-adapter/node-postgres/

版本：1\.1\.1
npm 元数据更新时间：2025-07-17T00:14:40.729Z
中文译文更新时间：2026-11-12T20:16:48.290Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40drizzle-adapter/node-postgres
原文对照：https://npmcn.com/package/%40drizzle-adapter/node-postgres/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：58.3 kB，61 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：4 个
- 首次发布：2024-12-03T05:42:14.267Z
- 最新版本发布：2025-07-17T00:14:40.494Z
- 近 30 天下载量：18014（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：11（近 12 个月 0 个）

## 中文简介

PostgreSQL 应用节点-postgres (pg)驱动程序对 Drizzle 适配器生态系统实施.

## 安装

```sh
npm install @drizzle-adapter/node-postgres
```

也可以使用：`pnpm add @drizzle-adapter/node-postgres`、`yarn add @drizzle-adapter/node-postgres`、`bun add @drizzle-adapter/node-postgres`

## README

# @ 细雨- 适应器/ 节点- 张贴

PostgreSQL 应用节点-postgres (pg)驱动程序对 Drizzle 适配器生态系统实施.

## 概览

这个 `@drizzle-adapter/node-postgres` 软件包为 Drizzle 适应器接口提供 PostgreSQL 执行 `node-postgres` 驾驶员。 虽然你不直接与此软件包互动( 您使用 `@drizzle-adapter/core` 相反,它使PostgreSQL能够在Drizzle适应器生态系统中提供支持.

## 为什么是节点派?

节点后置驱动程序具有若干优点:

-   **成熟和稳定**:多年生产试验
-   **本地连接集成**: 内置连接池管理
-   **完整特性支持**: 访问所有 PostgreSQL 特性
-   **二进制数据支持**: 高效的二进制数据处理
-   **发言稿**: 自动准备和缓存语句
-   **类型解析**: PostgreSQL 数据类型的原生处理
-   **SSL 支持**: 安全连接到完整的 SSL 配置
-   **主动维护**: 定期更新和安全补丁

## 安装

```bash
# Install both the core package and the PostgreSQL adapter
pnpm install @drizzle-adapter/core @drizzle-adapter/node-postgres
```

## 重要:适配器注册

适配器要正确使用 DrizzleAdapterFactory 操作,必须导入它进行自我注册的副作用:

```typescript
// Import for side effects - adapter will self-register
import '@drizzle-adapter/node-postgres';

// Now you can use the factory
import { DrizzleAdapterFactory } from '@drizzle-adapter/core';
```

## 使用量

### 配置

```typescript
import { DrizzleAdapterFactory, TypeDrizzleDatabaseConfig } from '@drizzle-adapter/core';

const config: TypeDrizzleDatabaseConfig = {
  DATABASE_DRIVER: 'node-postgres',
  DATABASE_URL: 'postgresql://user:password@localhost:5432/database'
};

const factory = new DrizzleAdapterFactory();
const adapter = factory.create(config);
```

### Schema 定义

```typescript
const dataTypes = adapter.getDataTypes();

const users = dataTypes.dbTable('users', {
  id: dataTypes.dbSerial('id').primaryKey(),
  name: dataTypes.dbText('name').notNull(),
  email: dataTypes.dbText('email').notNull().unique(),
  profile: dataTypes.dbJsonb('profile'),
  searchVector: dataTypes.dbTsVector('search_vector'),
  createdAt: dataTypes.dbTimestampTz('created_at').defaultNow()
});

const posts = dataTypes.dbTable('posts', {
  id: dataTypes.dbSerial('id').primaryKey(),
  userId: dataTypes.dbInteger('user_id')
    .references(() => users.id),
  title: dataTypes.dbText('title').notNull(),
  content: dataTypes.dbText('content').notNull(),
  tags: dataTypes.dbArray('tags', { type: 'text' }),
  metadata: dataTypes.dbJsonb('metadata'),
  published: dataTypes.dbBoolean('published').default(false),
  createdAt: dataTypes.dbTimestampTz('created_at').defaultNow()
});
```

### 基本 CRUD 操作

```typescript
import { eq, and, or, desc, sql } from 'drizzle-orm';

const connection = await adapter.getConnection();
const client = connection.getClient();

try {
  // INSERT
  // Single insert with returning
  const [newUser] = await client
    .insert(users)
    .values({
      name: 'John Doe',
      email: 'john@example.com',
      profile: { bio: 'Hello!' }
    })
    .returning();

  // Bulk insert
  await client
    .insert(posts)
    .values([
      {
        userId: newUser.id,
        title: 'First Post',
        content: 'Hello, world!',
        tags: ['hello', 'first']
      },
      {
        userId: newUser.id,
        title: 'Second Post',
        content: 'Another post',
        tags: ['second']
      }
    ]);

  // SELECT
  // Select all
  const allUsers = await client
    .select()
    .from(users);

  // Select with conditions
  const user = await client
    .select()
    .from(users)
    .where(eq(users.email, 'john@example.com'));

  // Select with join and array operations
  const postsWithTags = await client
    .select({
      userName: users.name,
      postTitle: posts.title,
      tags: posts.tags
    })
    .from(posts)
    .leftJoin(users, eq(posts.userId, users.id))
    .where(sql`${posts.tags} && ARRAY['hello']::text[]`)
    .orderBy(desc(posts.createdAt));

  // Full-text search
  const searchResults = await client
    .select()
    .from(posts)
    .where(sql`to_tsvector('english', ${posts.title} || ' ' || ${posts.content}) @@ to_tsquery('english', 'hello')`)
    .orderBy(desc(posts.createdAt));

  // UPDATE
  // Update with JSONB operations
  await client
    .update(users)
    .set({
      profile: sql`${users.profile} || '{"title": "New Title"}'::jsonb`
    })
    .where(eq(users.id, newUser.id));

  // DELETE
  await client
    .delete(posts)
    .where(
      and(
        eq(posts.userId, newUser.id),
        eq(posts.published, false)
      )
    );

} finally {
  // Always close the connection
  await connection.disconnect();
}
```

### 高级特性

#### 交易支持

```typescript
const connection = await adapter.getConnection();
const client = connection.getClient();

try {
  await client.transaction(async (tx) => {
    const [user] = await tx
      .insert(users)
      .values({
        name: 'John Doe',
        email: 'john@example.com'
      })
      .returning();

    await tx
      .insert(posts)
      .values({
        userId: user.id,
        title: 'My First Post',
        content: 'Hello, world!'
      });
  });
} finally {
  await connection.disconnect();
}
```

#### 全文搜索

```typescript
// Create search vector
await client.execute(sql`
  UPDATE ${posts}
  SET search_vector = to_tsvector('english', title || ' ' || content)
`);

// Create GiST index
await client.execute(sql`
  CREATE INDEX posts_search_idx ON ${posts} USING GiST (search_vector)
`);

// Search posts
const results = await client
  .select()
  .from(posts)
  .where(sql`${posts.searchVector} @@ to_tsquery('english', ${searchQuery})`)
  .orderBy(sql`ts_rank(${posts.searchVector}, to_tsquery('english', ${searchQuery})) DESC`);
```

#### 阵列操作

```typescript
// Find posts with specific tags
const taggedPosts = await client
  .select()
  .from(posts)
  .where(sql`${posts.tags} && ARRAY['typescript', 'postgresql']`);

// Add tag to existing tags
await client
  .update(posts)
  .set({
    tags: sql`array_append(${posts.tags}, 'new-tag')`
  })
  .where(eq(posts.id, postId));
```

## 最佳做法

1.  **连接管理**: 总是尝试/最后使用以确保连接被关闭
2.  **交易**: 相关业务使用交易
3.  **发言稿**: 报表自动编制并缓存
4.  **处理错误**: 执行适当的错误处理和重试
5.  **查询优化**: 使用索引和适当的查询规划

## 捐款

我们欢迎捐款! 请随意提交拉力请求 对于重大变动,请先开出一个问题来讨论你想要改变什么.

## 相关软件包

-   [@ 细雨适应器/ 核心](https://npmcn.com/package/%40drizzle-adapter/core) - 核心接口和类型
-   [@ 细雨适应器/ pg- core](https://npmcn.com/package/%40drizzle-adapter/pg-core) - 共享 PostgreSQL 功能
-   [@ 细雨适应器/ postgres-js](https://npmcn.com/package/%40drizzle-adapter/postgres-js) - 替代PostgreSQL适配器

## 常见问题

### @drizzle-adapter/node-postgres 是什么？

PostgreSQL 应用节点-postgres \(pg\)驱动程序对 Drizzle 适配器生态系统实施\.

### 如何安装 @drizzle-adapter/node-postgres？

在项目目录运行 npm install @drizzle-adapter/node-postgres，或使用 pnpm add / yarn add / bun add。

### @drizzle-adapter/node-postgres 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @drizzle-adapter/node-postgres 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @drizzle-adapter/node-postgres 可以商用吗？

@drizzle-adapter/node-postgres 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @drizzle-adapter/node-postgres 的下载量有多少？

根据 npm 官方下载统计，@drizzle-adapter/node-postgres 在 2026/10/13 – 2026/11/11 这 30 天内被下载 18,014 次，日均约 600 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @drizzle-adapter/node-postgres 还在维护吗？

最新版本 1\.1\.1 发布于 2025/07/17（1\.3 年前）；至今共发布 11 个版本，其中过去 12 个月发布了 0 个；首次发布于 2024/12/03。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

