pgx is a pure Go driver and toolkit for PostgreSQL providing a native high-performance interface with PostgreSQL-specific features plus a database/sql compatibility adapter.
import "github.com/jackc/pgx/v5"Execute a query that does not return rows (INSERT, UPDATE, DELETE, DDL).
func (c *Conn) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error)type CommandTag struct{ /* unexported */ }
func (ct CommandTag) String() string
func (ct CommandTag) RowsAffected() int64
func (ct CommandTag) Insert() bool
func (ct CommandTag) Update() bool
func (ct CommandTag) Delete() bool
func (ct CommandTag) Select() booltag, err := conn.Exec(ctx, "DELETE FROM users WHERE id = $1", 42)
fmt.Println(tag.RowsAffected()) // 1Send a query and get a Rows result set. Always close rows before reusing the connection.
func (c *Conn) Query(ctx context.Context, sql string, args ...any) (Rows, error)type Rows interface {
Close()
Err() error
CommandTag() pgconn.CommandTag
FieldDescriptions() []pgconn.FieldDescription
Next() bool
Scan(dest ...any) error
Values() ([]any, error)
RawValues() [][]byte
Conn() *Conn
}Low-level manual iteration:
rows, err := conn.Query(ctx, "SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var id int64
var name string
if err := rows.Scan(&id, &name); err != nil {
return err
}
// use id, name
}
return rows.Err()Execute a query expected to return at most one row.
func (c *Conn) QueryRow(ctx context.Context, sql string, args ...any) Rowtype Row interface {
Scan(dest ...any) error
}var name string
err := conn.QueryRow(ctx, "SELECT name FROM users WHERE id = $1", 42).Scan(&name)
if errors.Is(err, pgx.ErrNoRows) {
// not found
}These generic functions close rows automatically on return.
func CollectRows[T any](rows Rows, fn RowToFunc[T]) ([]T, error)func AppendRows[T any, S ~[]T](slice S, rows Rows, fn RowToFunc[T]) (S, error)func CollectOneRow[T any](rows Rows, fn RowToFunc[T]) (T, error)Returns ErrNoRows if no rows. Equivalent of QueryRow for generic results.
func CollectExactlyOneRow[T any](rows Rows, fn RowToFunc[T]) (T, error)Returns ErrNoRows if no rows, ErrTooManyRows if more than one.
func ForEachRow(rows Rows, scans []any, fn func() error) (pgconn.CommandTag, error)Scan into scans elements for each row and call fn. Closes rows on return.
var sum, n int32
rows, _ := conn.Query(ctx, "SELECT generate_series(1, $1)", 10)
_, err := pgx.ForEachRow(rows, []any{&n}, func() error {
sum += n
return nil
})type RowToFunc[T any] func(row CollectableRow) (T, error)
type CollectableRow interface {
FieldDescriptions() []pgconn.FieldDescription
Scan(dest ...any) error
Values() ([]any, error)
RawValues() [][]byte
}func RowTo[T any](row CollectableRow) (T, error)
func RowToAddrOf[T any](row CollectableRow) (*T, error)// Collect into []int32
rows, _ := conn.Query(ctx, "SELECT generate_series(1, $1)", 5)
nums, err := pgx.CollectRows(rows, pgx.RowTo[int32])
// nums => [1 2 3 4 5]func RowToMap(row CollectableRow) (map[string]any, error)func RowToStructByPos[T any](row CollectableRow) (T, error)
func RowToAddrOfStructByPos[T any](row CollectableRow) (*T, error)Fields are matched positionally to query columns. Fields tagged db:"-" are skipped.
type User struct {
ID int64
Name string
}
rows, _ := conn.Query(ctx, "SELECT id, name FROM users")
users, err := pgx.CollectRows(rows, pgx.RowToStructByPos[User])func RowToStructByName[T any](row CollectableRow) (T, error)
func RowToAddrOfStructByName[T any](row CollectableRow) (*T, error)Columns matched to struct fields by name (case-insensitive). Use db:"column_name" tag to override; db:"-" to skip. Struct must have exactly the same number of named fields as result columns.
type User struct {
ID int64 `db:"id"`
Name string `db:"name"`
}
rows, _ := conn.Query(ctx, "SELECT id, name FROM users")
users, err := pgx.CollectRows(rows, pgx.RowToStructByName[User])func RowToStructByNameLax[T any](row CollectableRow) (T, error)
func RowToAddrOfStructByNameLax[T any](row CollectableRow) (*T, error)Like ByName but allows struct to have more fields than result columns (unmatched fields remain zero).
type RowScanner interface {
ScanRow(rows Rows) error
}Implement this interface on a type to scan an entire row at once.
func ScanRow(typeMap *pgtype.Map, fieldDescriptions []pgconn.FieldDescription, values [][]byte, dest ...any) errorDecode raw row data from the pgconn level.
func RowsFromResultReader(typeMap *pgtype.Map, resultReader *pgconn.ResultReader) RowsWrap a pgconn-level ResultReader as a Rows for use with higher-level scan functions.
Pass a QueryExecMode as the first argument to Query/QueryRow/Exec:
rows, err := conn.Query(ctx, "SELECT ...", pgx.QueryExecModeSimpleProtocol, arg1, arg2)type QueryResultFormats []int16 // by column position: 0=text, 1=binary
type QueryResultFormatsByOID map[uint32]int16 // by OID: 0=text, 1=binaryPass as the first argument to control per-column format codes:
rows, err := conn.Query(ctx, "SELECT ...", pgx.QueryResultFormats{1, 0}, arg)type QueryRewriter interface {
RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error)
}Pass as the first argument to any query method to rewrite the SQL and args before execution. Used by NamedArgs and StrictNamedArgs.
type NamedArgs map[string]any
func (na NamedArgs) RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error)conn.Query(ctx, "SELECT * FROM widgets WHERE foo = @foo AND bar = @bar",
pgx.NamedArgs{"foo": 1, "bar": 2})type StrictNamedArgs map[string]any
func (sna StrictNamedArgs) RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error)Like NamedArgs but returns an error if any SQL placeholder is missing from the map, or if extra keys are provided.
type Identifier []string
func (ident Identifier) Sanitize() stringSanitize a PostgreSQL identifier for safe SQL interpolation:
tableName := pgx.Identifier{"public", "users"}.Sanitize()
// "public"."users"
conn.Exec(ctx, "SELECT * FROM "+tableName)var ErrNoRows error // errors.Is(err, pgx.ErrNoRows) or errors.Is(err, sql.ErrNoRows)
var ErrTooManyRows error
type ScanArgError struct {
ColumnIndex int
FieldName string
Err error
}
func (e ScanArgError) Error() string
func (e ScanArgError) Unwrap() errorUse errors.As(err, &pgconn.PgError{}) to inspect PostgreSQL server errors.
Low-level helper used by pgx internally to build extended protocol queries. Available for advanced use cases when constructing extended protocol queries manually via pgconn.
type ExtendedQueryBuilder struct {
ParamValues [][]byte
ParamFormats []int16
ResultFormats []int16
}
// Build encodes args using the provided type map and statement description,
// populating ParamValues, ParamFormats, and ResultFormats.
// If sd is nil, QueryExecModeExec behavior is used (all params as text format).
func (eqb *ExtendedQueryBuilder) Build(m *pgtype.Map, sd *pgconn.StatementDescription, args []any) errorUse with pgconn.PgConn.ExecParams or pgconn.PgConn.ExecPrepared when bypassing the high-level pgx query interface.
Install with Tessl CLI
npx tessl i tessl/golang-github-com-jackc-pgx-v5@5.8.0