Go 中使用 PGX 操作 PostgreSQL 入门

PGX 是 PostgreSQL 的纯 Go 驱动与工具包:可使用原生 API 或 database/sql 接口,原生支持 PG 专属类型、LISTEN/NOTIFY 与 COPY 协议,pgxpool 内置连接池。本文从连接到事务、批量操作全覆盖。

最佳实践
数据整理与查询插画

本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。

直接回答:PGX 是专为 PostgreSQL 设计的 Go 驱动——原生 API 暴露更多 PostgreSQL 专属能力,性能应按负载验证,原生支持 PG 专属类型(JSONB、数组、UUID)、LISTEN/NOTIFY 与 COPY 批量导入,pgxpool 提供内置连接池。直连用自有 API,也可作为 database/sql 的底层驱动混用。

为什么选 PGX

优势 说明
性能 绕开 database/sql 抽象层,专为 PG 优化
专属能力 COPY 协议、LISTEN/NOTIFY;逻辑复制使用配套 pglogrepl
类型支持 JSONB/数组/范围类型直接映射 Go 类型
连接池 pgxpool 内置,不用另配

连接与 CRUD

pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil { return err }
defer pool.Close()
if err := pool.Ping(ctx); err != nil { return err }

// 创建
_, err = pool.Exec(ctx, "INSERT INTO tasks(title) VALUES($1)", "写周报")
if err != nil { return err }

// 查询
var title string
err = pool.QueryRow(ctx, "SELECT title FROM tasks WHERE id=$1", 1).Scan(&title)
if err != nil { return err } // 按业务单独处理 pgx.ErrNoRows

// 多行
rows, err := pool.Query(ctx, "SELECT id, title FROM tasks")
if err != nil { return err }
defer rows.Close()
for rows.Next() {
    var id int
    var title string
    if err := rows.Scan(&id, &title); err != nil { return err }
    fmt.Println(id, title)
}
if err := rows.Err(); err != nil { return err }

占位符是 $1 $2(PG 风格),不是 MySQL 的 ?。

事务与批量

tx, err := pool.Begin(ctx)
if err != nil { return err }
defer func() {
    cleanup, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    _ = tx.Rollback(cleanup) // 已提交时返回 ErrTxClosed,无需再次回滚
}()
if _, err := tx.Exec(ctx, "UPDATE tasks SET title=$1 WHERE id=$2", "已审阅", 1); err != nil {
    return err
}
return tx.Commit(ctx)

批量操作用 pgx.Batch 一次往返发多条 SQL;大批量导入走 CopyFrom——减少逐行发送开销,但不能保证固定倍数。SendBatch 返回的 BatchResults 必须关闭并检查错误后再复用连接。

预编译与 PG 专属类型

pgx v5 默认执行模式可自动准备并缓存语句;通常不用手工 Prepare,连接池场景还要注意语句与连接的绑定;JSONB 直接 Scan 进 map[string]any 或结构体,数组进 []string——PGX 的类型映射是它相对 database/sql 最实在的体验升级。

常见问题(FAQ)

Q:PGX 和 database/sql 怎么选?
A:纯 PostgreSQL 项目直接用 PGX 原生 API(性能+类型支持);需要数据库无关抽象或 ORM(GORM/sqlx 底层)时走 database/sql 接口。

Q:连接池大小怎么配?
A:pgxpool 默认上限合理起步(连接字符串参数是 pool_max_conns;分配预算时从 PG max_connections 扣除运维和其他客户端预留,再分给各实例)。池太大反而拖垮数据库——PG 的强项不是海量连接。

Q:LISTEN/NOTIFY 能干什么?
A:可用于事件提示,但 NOTIFY 不是持久消息队列,断线期间的通知无法自动补收。用专用连接 LISTEN 并实现重连及状态核对,不能把它当可靠任务交付机制。

官方参考

资料核对日期:2026-09-29。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台