README
¶
PostgreSQL client for Golang 
Supports:
- Basic types: integers, floats, string, bool, time.Time.
- sql.NullBool, sql.NullString, sql.NullInt64 and sql.NullFloat64.
sql:",null"
struct tag which marshalls zero struct fields as SQLNULL
and completely omits them fromINSERT
queries.- sql.Scanner and sql/driver.Valuer interfaces.
- Structs, maps and arrays are marshalled as JSON by default.
- PostgreSQL Arrays using array tag and Array wrapper.
- Transactions.
- Prepared statements.
- Notifications using
LISTEN
andNOTIFY
. - Copying data using
COPY FROM
andCOPY TO
. - Timeouts.
- Automatic connection pooling.
- Queries retries on network errors.
- Working with models using ORM and SQL.
- Scanning variables using ORM and SQL.
- SelectOrCreate using upserts.
- HasOne, HasMany and ManyToMany.
- Migrations.
- Sharding.
API docs: http://godoc.org/gopkg.in/pg.v4. Examples: http://godoc.org/gopkg.in/pg.v4#pkg-examples.
Table of contents
Installation
Install:
go get gopkg.in/pg.v4
Quickstart
package pg_test
import (
"fmt"
"gopkg.in/pg.v4"
)
type User struct {
Id int64
Name string
Emails []string
}
func (u User) String() string {
return fmt.Sprintf("User<%d %s %v>", u.Id, u.Name, u.Emails)
}
type Story struct {
Id int64
Title string
UserId int64
User *User
}
func (s Story) String() string {
return fmt.Sprintf("Story<%d %s %s>", s.Id, s.Title, s.User)
}
func createSchema(db *pg.DB) error {
queries := []string{
`CREATE TEMP TABLE users (id serial, name text, emails jsonb)`,
`CREATE TEMP TABLE stories (id serial, title text, user_id bigint)`,
}
for _, q := range queries {
_, err := db.Exec(q)
if err != nil {
return err
}
}
return nil
}
func ExampleDB_Query() {
db := pg.Connect(&pg.Options{
User: "postgres",
})
err := createSchema(db)
if err != nil {
panic(err)
}
user1 := &User{
Name: "admin",
Emails: []string{"admin1@admin", "admin2@admin"},
}
err = db.Create(user1)
if err != nil {
panic(err)
}
err = db.Create(&User{
Name: "root",
Emails: []string{"root1@root", "root2@root"},
})
if err != nil {
panic(err)
}
story1 := &Story{
Title: "Cool story",
UserId: user1.Id,
}
err = db.Create(story1)
if err != nil {
panic(err)
}
var user User
err = db.Model(&user).Where("id = ?", user1.Id).Select()
if err != nil {
panic(err)
}
var users []User
err = db.Model(&users).Select()
if err != nil {
panic(err)
}
var story Story
err = db.Model(&story).
Column("story.*", "User").
Where("story.id = ?", story1.Id).
Select()
if err != nil {
panic(err)
}
fmt.Println(user)
fmt.Println(users[0], users[1])
fmt.Println(story)
// Output: User<1 admin [admin1@admin admin2@admin]>
// User<1 admin [admin1@admin admin2@admin]> User<2 root [root1@root root2@root]>
// Story<1 Cool story User<1 admin [admin1@admin admin2@admin]>>
}
Why go-pg
-
No
rows.Close
to manually manage connections. -
go-pg automatically maps rows on Go structs and slice.
-
go-pg is 2x-10x faster than GORM on querying 100 rows from table.
BenchmarkQueryRowsGopgOptimized-4 10000 158443 ns/op 83432 B/op 625 allocs/op BenchmarkQueryRowsGopgReflect-4 10000 189014 ns/op 94759 B/op 826 allocs/op BenchmarkQueryRowsGopgORM-4 10000 199685 ns/op 95024 B/op 830 allocs/op BenchmarkQueryRowsStdlibPq-4 5000 242135 ns/op 161646 B/op 1324 allocs/op BenchmarkQueryRowsGORM-4 2000 704366 ns/op 396184 B/op 6767 allocs/op
-
go-pg generates much more effecient queries for joins.
Has one relationBenchmarkModelHasOneGopg-4 5000 313091 ns/op 78481 B/op 1290 allocs/op BenchmarkModelHasOneGORM-4 500 3849634 ns/op 1529982 B/op 71636 allocs/op
go-pg:
db.Model(&books).Column("book.*", "Author").Limit(100).Select()
SELECT "book".*, "author"."id" AS "author__id", "author"."name" AS "author__name" FROM "books" AS "book" LEFT JOIN "authors" AS "author" ON "author"."id" = "book"."author_id" LIMIT 100
GORM:
db.Preload("Author").Limit(100).Find(&books).Error
SELECT * FROM "books" LIMIT 100 SELECT * FROM "authors" WHERE ("id" IN ('1','2'...'100'))
Has many relationBenchmarkModelHasManyGopg-4 500 3034576 ns/op 409288 B/op 8700 allocs/op BenchmarkModelHasManyGORM-4 50 24677309 ns/op 10121839 B/op 519411 allocs/op
go-pg:
db.Model(&books).Column("book.*", "Translations").Limit(100).Select()
SELECT "book".* FROM "books" AS "book" LIMIT 100 SELECT "translation".* FROM "translations" AS "translation" WHERE ("translation"."book_id") IN ((100), (101), ... (199));
GORM:
db.Preload("Translations").Limit(100).Find(&books).Error
SELECT * FROM "books" LIMIT 100; SELECT * FROM "translations" WHERE ("book_id" IN (1, 2, ..., 100)); SELECT * FROM "authors" WHERE ("book_id" IN (1, 2, ..., 100));
Many to many relationBenchmarkModelHasMany2ManyGopg-4 500 3329123 ns/op 394738 B/op 9739 allocs/op BenchmarkModelHasMany2ManyGORM-4 200 7847630 ns/op 3350304 B/op 66239 allocs/op
go-pg:
db.Model(&books).Column("book.*", "Genres").Limit(100).Select()
SELECT "book"."id" FROM "books" AS "book" LIMIT 100; SELECT * FROM "genres" AS "genre" JOIN "book_genres" AS "book_genre" ON ("book_genre"."book_id") IN ((1), (2), ..., (100)) WHERE "genre"."id" = "book_genre"."genre_id";
GORM:
db.Preload("Genres").Limit(100).Find(&books).Error
SELECT * FROM "books" LIMIT 100; SELECT * FROM "genres" INNER JOIN "book_genres" ON "book_genres"."genre_id" = "genres"."id" WHERE ("book_genres"."book_id" IN ((1), (2), ..., (100)));
Howto
Please go through examples to get the idea how to use this package.
Model definition
type Genre struct {
TableName struct{} `sql:"genres"` // specifies custom table name
Id int // Id is automatically detected as primary key
Name string
Rating int `sql:"-"` // - is used to ignore field
Books []Book `pg:",many2many:book_genres"` // many to many relation
ParentId int `sql:",null"`
Subgenres []Genre `pg:",fk:Parent"` // fk specifies prefix for foreign key (ParentId)
}
func (g Genre) String() string {
return fmt.Sprintf("Genre<Id=%d Name=%q>", g.Id, g.Name)
}
type Author struct {
ID int // both "Id" and "ID" are detected as primary key
Name string
Books []Book // has many relation
}
func (a Author) String() string {
return fmt.Sprintf("Author<ID=%d Name=%q>", a.ID, a.Name)
}
type BookGenre struct {
BookId int `sql:",pk"` // pk tag is used to mark field as primary key
GenreId int `sql:",pk"`
Genre_Rating int // belongs to and is copied to Genre model
}
type Book struct {
Id int
Title string
AuthorID int
Author *Author // has one relation
EditorID int
Editor *Author // has one relation
CreatedAt time.Time
Genres []Genre `pg:",many2many:book_genres" gorm:"many2many:book_genres;"` // many to many relation
Translations []Translation // has many relation
Comments []Comment `pg:",polymorphic:Trackable"` // has many polymorphic relation
}
func (b Book) String() string {
return fmt.Sprintf("Book<Id=%d Title=%q>", b.Id, b.Title)
}
type Translation struct {
Id int
BookId int
Book *Book // belongs to relation
Lang string
Comments []Comment `pg:",polymorphic:Trackable"` // has many polymorphic relation
}
type Comment struct {
TrackableId int `sql:",pk"` // Book.Id or Translation.Id
TrackableType string `sql:",pk"` // "book" or "translation"
Text string
}
Documentation
¶
Overview ¶
Package gopkg.in/pg.v4 implements a PostgreSQL client.
Index ¶
- Variables
- func Array(v interface{}) *types.Array
- func F(field string, params ...interface{}) types.F
- func Q(query string, params ...interface{}) types.Q
- func Scan(values ...interface{}) orm.ColumnScanner
- func SetLogger(logger *log.Logger)
- type DB
- func (db *DB) Begin() (*Tx, error)
- func (db *DB) Close() error
- func (db *DB) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (*types.Result, error)
- func (db *DB) CopyTo(w io.Writer, query interface{}, params ...interface{}) (*types.Result, error)
- func (db *DB) Create(model interface{}) error
- func (db *DB) Delete(model interface{}) error
- func (db *DB) Exec(query interface{}, params ...interface{}) (res *types.Result, err error)
- func (db *DB) ExecOne(query interface{}, params ...interface{}) (*types.Result, error)
- func (db *DB) FormatQuery(dst []byte, query string, params ...interface{}) []byte
- func (db *DB) Listen(channels ...string) (*Listener, error)
- func (db *DB) Model(model interface{}) *orm.Query
- func (db *DB) Options() *Options
- func (db *DB) Prepare(q string) (*Stmt, error)
- func (db *DB) Query(model, query interface{}, params ...interface{}) (res *types.Result, err error)
- func (db *DB) QueryOne(model, query interface{}, params ...interface{}) (*types.Result, error)
- func (db *DB) RunInTransaction(fn func(*Tx) error) error
- func (db *DB) Update(model interface{}) error
- func (db *DB) WithTimeout(d time.Duration) *DB
- type Error
- type IntSet
- type Ints
- type Listener
- type Options
- type Stmt
- func (stmt *Stmt) Close() error
- func (stmt *Stmt) Exec(params ...interface{}) (res *types.Result, err error)
- func (stmt *Stmt) ExecOne(params ...interface{}) (*types.Result, error)
- func (stmt *Stmt) Query(model interface{}, params ...interface{}) (res *types.Result, err error)
- func (stmt *Stmt) QueryOne(model interface{}, params ...interface{}) (*types.Result, error)
- type Strings
- type Tx
- func (tx *Tx) Commit() (err error)
- func (tx *Tx) CopyFrom(r io.Reader, query string, params ...interface{}) (*types.Result, error)
- func (tx *Tx) Create(model interface{}) error
- func (tx *Tx) Delete(model interface{}) error
- func (tx *Tx) Exec(query interface{}, params ...interface{}) (*types.Result, error)
- func (tx *Tx) ExecOne(query interface{}, params ...interface{}) (*types.Result, error)
- func (tx *Tx) FormatQuery(dst []byte, query string, params ...interface{}) []byte
- func (tx *Tx) Model(model interface{}) *orm.Query
- func (tx *Tx) Prepare(q string) (*Stmt, error)
- func (tx *Tx) Query(model interface{}, query interface{}, params ...interface{}) (*types.Result, error)
- func (tx *Tx) QueryOne(model interface{}, query interface{}, params ...interface{}) (*types.Result, error)
- func (tx *Tx) Rollback() (err error)
- func (tx *Tx) Update(model interface{}) error
Examples ¶
- Array
- Connect
- DB.Begin
- DB.CopyFrom
- DB.Create
- DB.Create (OnConflict)
- DB.Create (SelectOrCreate)
- DB.Delete
- DB.Delete (MultipleRows)
- DB.Exec
- DB.Model
- DB.Model (CountRows)
- DB.Model (FirstRow)
- DB.Model (HasMany)
- DB.Model (HasOne)
- DB.Model (LastRow)
- DB.Model (ManyToMany)
- DB.Model (NullEmptyValue)
- DB.Model (PostgresArrayStructTag)
- DB.Model (SelectAllColumns)
- DB.Model (SelectSomeColumns)
- DB.Model (SelectSomeVars)
- DB.Prepare
- DB.Query
- DB.QueryOne
- DB.QueryOne (Returning_id)
- DB.RunInTransaction
- DB.Update
- DB.Update (MultipleRows)
- DB.Update (SomeColumns)
- DB.Update (UsingSqlFunction)
- DB.WithTimeout
- F
- Ints
- Ints (In)
- Listener
- Q
- Scan
- Strings
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoRows = internal.ErrNoRows ErrMultiRows = internal.ErrMultiRows )
var Discard orm.Discard
Discard is used with Query and QueryOne to discard rows.
Functions ¶
func Array ¶
Array returns an Array type that represents PostgreSQL array of any type.
Example ¶
Output: [one@example.com two@example.com]
func F ¶
F returns a ValueAppender that represents SQL identifier, e.g. table or column name.
Example ¶
Output: Book<Id=1 Title="book 1">
func Scan ¶
func Scan(values ...interface{}) orm.ColumnScanner
Scan returns ColumnScanner that copies the columns in the row into the values.
Example ¶
Output: foo bar <nil>
Types ¶
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
DB is a database handle representing a pool of zero or more underlying connections. It's safe for concurrent use by multiple goroutines.
func Connect ¶
Connect connects to a database using provided options.
The returned DB is safe for concurrent use by multiple goroutines and maintains its own connection pool.
Example ¶
Output: <nil>
func (*DB) Begin ¶
Begin starts a transaction. Most callers should use RunInTransaction instead.
Example ¶
Output: 1
func (*DB) Close ¶
Close closes the database client, releasing any open resources.
It is rare to Close a DB, as the DB handle is meant to be long-lived and shared between many goroutines.
func (*DB) CopyFrom ¶
func (db *DB) CopyFrom(r io.Reader, query interface{}, params ...interface{}) (*types.Result, error)
CopyFrom copies data from reader to a table.
Example ¶
Output: hello,5 foo,3
func (*DB) Create ¶
Create inserts the model into database.
Example ¶
Output: Book<Id=4 Title="new book">
Example (OnConflict) ¶
Output: created did nothing
Example (SelectOrCreate) ¶
Output: true Author<ID=2 Name="R. Scott Bakker">
func (*DB) Delete ¶
Delete deletes the model from database.
Example ¶
Output: pg: no rows in result set
Example (MultipleRows) ¶
Output: deleted 3 left 0
func (*DB) Exec ¶
Exec executes a query ignoring returned rows. The params are for any placeholder parameters in the query.
Example ¶
Output: -1 <nil>
func (*DB) ExecOne ¶
ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows.
func (*DB) FormatQuery ¶
func (*DB) Model ¶
Model returns new query for the model.
Example ¶
Output: User<1 admin [admin1@admin admin2@admin]> User<1 admin [admin1@admin admin2@admin]> User<2 root [root1@root root2@root]> Story<1 Cool story User<1 admin [admin1@admin admin2@admin]>>
Example (CountRows) ¶
Output: 3
Example (FirstRow) ¶
Output: Book<Id=1 Title="book 1">
Example (HasMany) ¶
Output: Book<Id=1 Title="book 1"> Book<Id=2 Title="book 2">
Example (HasOne) ¶
Output: Book<Id=1 Title="book 1"> Author<ID=1 Name="author 1">
Example (LastRow) ¶
Output: Book<Id=3 Title="book 3">
Example (ManyToMany) ¶
Output: Item 1 Subitems 2 3
Example (NullEmptyValue) ¶
Output: false
Example (PostgresArrayStructTag) ¶
Output: {1 [one@example.com two@example.com] [123 321]}
Example (SelectAllColumns) ¶
Output: Book<Id=1 Title="book 1"> 1
Example (SelectSomeColumns) ¶
Output: Book<Id=1 Title="">
Example (SelectSomeVars) ¶
Output: 1 book 1
func (*DB) Prepare ¶
Prepare creates a prepared statement for later queries or executions. Multiple queries or executions may be run concurrently from the returned statement.
Example ¶
Output: foo bar <nil>
func (*DB) Query ¶
Query executes a query that returns rows, typically a SELECT. The params are for any placeholder parameters in the query.
Example ¶
Output: User<1 admin [admin1@admin admin2@admin]> User<1 admin [admin1@admin admin2@admin]> User<2 root [root1@root root2@root]> Story<1 Cool story User<1 admin [admin1@admin admin2@admin]>>
func (*DB) QueryOne ¶
QueryOne acts like Query, but query must return only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows.
Example ¶
Output: 1 {admin}
Example (Returning_id) ¶
Output: {1 admin}
func (*DB) RunInTransaction ¶
RunInTransaction runs a function in a transaction. If function returns an error transaction is rollbacked, otherwise transaction is committed.
Example ¶
Output: 1
func (*DB) Update ¶
Update updates the model in database.
Example ¶
Output: Book<Id=1 Title="updated book 1">
Example (MultipleRows) ¶
Output: Book<Id=1 Title="prefix book 1 suffix"> Book<Id=2 Title="prefix book 2 suffix">
Example (SomeColumns) ¶
Output: Book<Id=1 Title="updated book 1"> 1
Example (UsingSqlFunction) ¶
Output: Book<Id=1 Title="prefix book 1 suffix">
type IntSet ¶
type IntSet map[int64]struct{}
func (*IntSet) NewModel ¶
func (set *IntSet) NewModel() orm.ColumnScanner
type Ints ¶
type Ints []int64
Example ¶
Output: [0 1 2 3 4 5 6 7 8 9 10] <nil>
Example (In) ¶
Output: SELECT * FROM table WHERE id IN (1,2,3)
func (*Ints) NewModel ¶
func (ints *Ints) NewModel() orm.ColumnScanner
type Listener ¶
type Listener struct {
// contains filtered or unexported fields
}
Not thread-safe.
Example ¶
Output: mychan "hello world" <nil>
type Options ¶
type Options struct { // The network type, either tcp or unix. // Default is tcp. Network string // TCP host:port or Unix socket depending on Network. Addr string User string Password string Database string // Whether to use secure TCP/IP connections (TLS). SSL bool // PostgreSQL run-time configuration parameters to be set on connection. Params map[string]interface{} // The maximum number of retries before giving up. // Default is to not retry failed queries. MaxRetries int // The deadline for establishing new connections. If reached, // dial will fail with a timeout. // Default is 5 seconds. DialTimeout time.Duration // The timeout for socket reads. If reached, commands will fail // with a timeout error instead of blocking. // Default is no timeout. ReadTimeout time.Duration // The timeout for socket writes. If reached, commands will fail // with a timeout error instead of blocking. // Default is no timeout. WriteTimeout time.Duration // The maximum number of open socket connections. // Default is 10 connections. PoolSize int // The amount of time client waits for free connection if all // connections are busy before returning an error. // Default is 5 seconds. PoolTimeout time.Duration // The amount of time after which client closes idle connections. // Default is to not close idle connections. IdleTimeout time.Duration // The frequency of idle checks. // Default is 1 minute. IdleCheckFrequency time.Duration }
Database connection options.
type Stmt ¶
type Stmt struct {
// contains filtered or unexported fields
}
Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines.
func (*Stmt) ExecOne ¶
ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows.
type Strings ¶
type Strings []string
Example ¶
Output: [foo bar] <nil>
func (Strings) AppendValue ¶
func (*Strings) NewModel ¶
func (strings *Strings) NewModel() orm.ColumnScanner
type Tx ¶
type Tx struct {
// contains filtered or unexported fields
}
Not thread-safe.
func (*Tx) ExecOne ¶
ExecOne acts like Exec, but query must affect only one row. It returns ErrNoRows error when query returns zero rows or ErrMultiRows when query returns multiple rows.
func (*Tx) FormatQuery ¶
func (*Tx) Query ¶
func (tx *Tx) Query(model interface{}, query interface{}, params ...interface{}) (*types.Result, error)
Query executes a query with the given parameters in a transaction.