Documentation
¶
Overview ¶
Package pgxscan allows scanning data into Go structs and other composite types, when working with pgx library native interface.
Essentially, pgxscan is a wrapper around github.com/georgysavva/scany/dbscan package. pgxscan connects github.com/jackc/pgx/v4 native interface with dbscan functionality. It contains adapters that are meant to work with pgx.Rows and proxy all calls to dbscan. pgxscan mirrors all capabilities provided by dbscan. It's encouraged to read dbscan docs first to get familiar with all concepts and features.
How to use ¶
The most common way to work with pgxscan is to call Select or Get functions.
Use Select to query multiple records:
type User struct {
ID string
Name string
Email string
Age int
}
db, _ := pgxpool.Connect(ctx, "example-connection-url")
var users []*User
pgxscan.Select(ctx, db, &users, `SELECT id, name, email, age FROM users`)
// users variable now contains data from all rows.
Use Get to query exactly one record:
type User struct {
ID string
Name string
Email string
Age int
}
db, _ := pgxpool.Connect(ctx, "example-connection-url")
var user User
pgxscan.Get(ctx, db, &user, `SELECT id, name, email, age FROM users WHERE id='bob'`)
// user variable now contains data from the single row.
Note about pgx custom types ¶
pgx has a concept of custom types: https://pkg.go.dev/github.com/jackc/pgx/v4?tab=doc#hdr-Custom_Type_Support.
In order to use them with pgxscan you must specify your custom types by value, not by a pointer. Let's take the pgx custom type pgtype.Text as an example:
type User struct {
ID string
Name *pgtype.Text // pgxscan won't be able to scan data into a field defined that way.
Bio pgtype.Text // This is a valid use of pgx custom types, pgxscan will handle it easily.
}
This happens because struct fields are always passed to the underlying pgx.Rows.Scan() by pointer, and if the field type is *pgtype.Text, pgx.Rows.Scan() will receive **pgtype.Text type. pgx can't handle **pgtype.Text, since only *pgtype.Text implements pgx custom type interface.
Supported pgx version ¶
pgxscan only works with pgx v4. So the import path of your pgx must be: "github.com/jackc/pgx/v4".
Index ¶
- func Get(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- func NotFound(err error) bool
- func ScanAll(dst interface{}, rows pgx.Rows) error
- func ScanOne(dst interface{}, rows pgx.Rows) error
- func ScanRow(dst interface{}, rows pgx.Rows) error
- func Select(ctx context.Context, db Querier, dst interface{}, query string, ...) error
- type Querier
- type RowScanner
- type RowsAdapter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Get ¶ added in v0.2.0
Get is a high-level function that queries rows and calls the ScanOne function. See ScanOne for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
db, _ := pgxpool.Connect(ctx, "example-connection-url")
var user User
if err := pgxscan.Get(
ctx, db, &user, `SELECT user_id, name, email, age FROM users WHERE user_id='bob'`,
); err != nil {
// Handle query or rows processing error.
}
// user variable now contains data from all rows.
func NotFound ¶
NotFound is a wrapper around the dbscan.NotFound function. See dbscan.NotFound for details.
func ScanAll ¶
ScanAll is a wrapper around the dbscan.ScanAll function. See dbscan.ScanAll for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age FROM users`)
var users []*User
if err := pgxscan.ScanAll(&users, rows); err != nil {
// Handle rows processing error.
}
// users variable now contains data from all rows.
func ScanOne ¶
ScanOne is a wrapper around the dbscan.ScanOne function. See dbscan.ScanOne for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age FROM users WHERE user_id='bob'`)
var user User
if err := pgxscan.ScanOne(&user, rows); err != nil {
// Handle rows processing error.
}
// user variable now contains data from the single row.
func ScanRow ¶
ScanRow is a wrapper around the dbscan.ScanRow function. See dbscan.ScanRow for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age FROM users`)
// Make sure rows are always closed.
defer rows.Close()
for rows.Next() {
var user User
if err := pgxscan.ScanRow(&user, rows); err != nil {
// Handle row scanning error.
}
// user variable now contains data from the current row.
}
if err := rows.Err(); err != nil {
// Handle rows final error.
}
func Select ¶ added in v0.2.0
func Select(ctx context.Context, db Querier, dst interface{}, query string, args ...interface{}) error
Select is a high-level function that queries rows and calls the ScanAll function. See ScanAll for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
db, _ := pgxpool.Connect(ctx, "example-connection-url")
var users []*User
if err := pgxscan.Select(
ctx, db, &users, `SELECT user_id, name, email, age FROM users`,
); err != nil {
// Handle query or rows processing error.
}
// users variable now contains data from all rows.
Types ¶
type Querier ¶
type Querier interface {
Query(ctx context.Context, query string, args ...interface{}) (pgx.Rows, error)
}
Querier is something that pgxscan can query and get the pgx.Rows from. For example, it can be: *pgxpool.Pool, *pgx.Conn or pgx.Tx.
type RowScanner ¶
type RowScanner struct {
*dbscan.RowScanner
}
RowScanner is a wrapper around the dbscan.RowScanner type. See dbscan.RowScanner for details.
Example ¶
type User struct {
ID string `db:"user_id"`
Name string
Email string
Age int
}
// Query pgx.Rows from the database.
db, _ := pgxpool.Connect(ctx, "example-connection-url")
rows, _ := db.Query(ctx, `SELECT user_id, name, email, age FROM users`)
// Make sure rows are always closed.
defer rows.Close()
rs := pgxscan.NewRowScanner(rows)
for rows.Next() {
var user User
if err := rs.Scan(&user); err != nil {
// Handle row scanning error.
}
// user variable now contains data from the current row.
}
if err := rows.Err(); err != nil {
// Handle rows final error.
}
func NewRowScanner ¶
func NewRowScanner(rows pgx.Rows) *RowScanner
NewRowScanner returns a new RowScanner instance.
type RowsAdapter ¶
RowsAdapter makes pgx.Rows compliant with the dbscan.Rows interface. See dbscan.Rows for details.
func NewRowsAdapter ¶
func NewRowsAdapter(rows pgx.Rows) *RowsAdapter
NewRowsAdapter returns a new RowsAdapter instance.
func (RowsAdapter) Close ¶
func (ra RowsAdapter) Close() error
Close implements the dbscan.Rows.Close method.
func (RowsAdapter) Columns ¶
func (ra RowsAdapter) Columns() ([]string, error)
Columns implements the dbscan.Rows.Columns method.