@drizzle-adapter/node-postgres

中文文档
1.1.1发布于 2025/07/17MITTypeScriptES Module近 30 天下载 1.8万

PostgreSQL adapter implementation for the Drizzle Adapter ecosystem using the node-postgres (pg) driver.

原始使用文档
文档目录12 节
  1. Overview
  2. Why node-postgres?
  3. Installation
  4. Important: Adapter Registration
  5. Usage
  6. Configuration
  7. Schema Definition
  8. Basic CRUD Operations
  9. Advanced Features
  10. Best Practices
  11. Contributing
  12. Related Packages

@drizzle-adapter/node-postgres

PostgreSQL adapter implementation for the Drizzle Adapter ecosystem using the node-postgres (pg) driver.

Overview

The @drizzle-adapter/node-postgres package provides the PostgreSQL implementation for the Drizzle Adapter interface using the widely-adopted node-postgres driver. While you don't interact with this package directly (you use @drizzle-adapter/core instead), it enables PostgreSQL support in the Drizzle Adapter ecosystem.

Why node-postgres?

The node-postgres driver offers several advantages:

  • Mature and Stable: Battle-tested in production for many years
  • Native Connection Pooling: Built-in connection pool management
  • Full Feature Support: Access to all PostgreSQL features
  • Binary Data Support: Efficient binary data handling
  • Prepared Statements: Automatic statement preparation and caching
  • Type Parsing: Native handling of PostgreSQL data types
  • SSL Support: Secure connections with full SSL configuration
  • Active Maintenance: Regular updates and security patches

Installation

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

Important: Adapter Registration

For the adapter to work correctly with the DrizzleAdapterFactory, you must import it for its self-registration side effects:

// 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';

Usage

Configuration

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 Definition

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()
});

Basic CRUD Operations

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: '[email protected]',
      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, '[email protected]'));

  // 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();
}

Advanced Features

Transaction Support

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: '[email protected]'
      })
      .returning();

    await tx
      .insert(posts)
      .values({
        userId: user.id,
        title: 'My First Post',
        content: 'Hello, world!'
      });
  });
} finally {
  await connection.disconnect();
}
// 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`);

Array Operations

// 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));

Best Practices

  1. Connection Management: Always use try/finally to ensure connections are closed
  2. Transactions: Use transactions for related operations
  3. Prepared Statements: Statements are automatically prepared and cached
  4. Error Handling: Implement proper error handling and retries
  5. Query Optimization: Use indexes and proper query planning

Contributing

We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

版本与发布记录

@drizzle-adapter/node-postgres 共发布 11 个版本,首次发布于 2024/12/03;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.1.1latest2025/07/171.3 年前
1.0.102025/07/121.3 年前
1.1.02025/07/121.3 年前
1.0.92025/04/201.6 年前
1.0.82025/03/101.7 年前
1.0.72024/12/231.9 年前

关于 @drizzle-adapter/node-postgres 的常见问题

@drizzle-adapter/node-postgres 是什么?

PostgreSQL adapter implementation for the Drizzle Adapter ecosystem using the node-postgres (pg) driver.

如何安装 @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 和提交记录判断。