What it is
sqlx is a thin set of extensions over Go's database/sql that adds struct scanning, named parameters and helpers, without becoming an ORM.
sqlx wraps sql.DB and adds Get, Select, StructScan and named queries. You keep full control of the SQL; sqlx only removes the mapping boilerplate.
Installation
go get github.com/jmoiron/sqlxGetting started
The smallest useful thing you can do with it, and what each part means.
type Book struct {
ID int `db:"id"`
Title string `db:"title"`
Year int `db:"year"`
}
db, err := sqlx.Connect("postgres", dsn)
// One row.
var book Book
err = db.GetContext(ctx, &book, "SELECT id, title, year FROM books WHERE id = $1", 42)
// Many rows.
var books []Book
err = db.SelectContext(ctx, &books, "SELECT id, title, year FROM books WHERE year > $1", 1990)_, err := db.NamedExecContext(ctx,
`INSERT INTO books (title, year) VALUES (:title, :year)`,
map[string]any{"title": "Dune", "year": 1965})
// Or straight from a struct, using the db tags.
_, err = db.NamedExecContext(ctx,
`INSERT INTO books (title, year) VALUES (:title, :year)`, book)Advanced usage
Where the library earns its place over a simpler alternative.
ids := []int{1, 2, 3, 4}
// database/sql cannot expand a slice — sqlx.In rewrites the query.
query, args, err := sqlx.In("SELECT * FROM books WHERE id IN (?)", ids)
if err != nil { return err }
// Rebind converts ? placeholders to the driver's style ($1, $2 for Postgres).
query = db.Rebind(query)
var books []Book
err = db.SelectContext(ctx, &books, query, args...)Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- missing destination name X in *Book
- A selected column has no matching field or db tag. Add the tag, alias the column, or select fewer columns.
- sql: no rows in result set
- Get found nothing. Check with errors.Is(err, sql.ErrNoRows) and treat it as a not-found case rather than a failure.
Best practices
- Tag every struct field with db:"column" — sqlx will error on unmatched columns, which catches typos early.
- Use the Context variants of every method so queries respect cancellation.
- Set db.SetMaxOpenConns and SetConnMaxLifetime; the defaults are unlimited and will exhaust the database under load.
- Prefer sqlx.In over building IN lists by hand.
Background
Why it exists, and what it was reacting to.
Written by Jason Moiron for developers who wanted to keep writing SQL but stop writing rows.Scan boilerplate. It stays deliberately close to the standard library, so everything you know about database/sql still applies.
