Convert Figma logo to code with AI

go-pg logopg

Golang ORM with focus on PostgreSQL features and performance

5,665
405
5,665
117

Top Related Projects

3,670

SQL-first Golang ORM

16,124

general purpose extensions to golang's database/sql

10,547

PostgreSQL driver and toolkit for Go

36,742

The fantastic ORM library for Golang, aims to be developer friendly

9,065

Pure Go Postgres driver for database/sql

12,916

Generate type-safe code from SQL

Quick Overview

go-pg/pg is a powerful PostgreSQL client and ORM for Go. It provides a high-performance, feature-rich interface for interacting with PostgreSQL databases, offering both low-level database operations and high-level ORM functionality.

Pros

  • High performance with efficient query execution and connection pooling
  • Feature-rich ORM with support for complex queries, transactions, and migrations
  • Strong type safety and compile-time checks for SQL queries
  • Extensive documentation and active community support

Cons

  • Steeper learning curve compared to some simpler database libraries
  • Specific to PostgreSQL, limiting database portability
  • May be overkill for simple database operations or small projects
  • Requires manual management of database schema changes

Code Examples

  1. Connecting to a database:
db := pg.Connect(&pg.Options{
    Addr:     "localhost:5432",
    User:     "postgres",
    Password: "password",
    Database: "mydb",
})
defer db.Close()
  1. Inserting a record using the ORM:
type User struct {
    ID   int64
    Name string
    Age  int
}

user := &User{
    Name: "John Doe",
    Age:  30,
}

_, err := db.Model(user).Insert()
if err != nil {
    panic(err)
}
  1. Querying records with a complex condition:
var users []User
err := db.Model(&users).
    Where("age > ?", 25).
    Where("name LIKE ?", "%Doe%").
    Order("name ASC").
    Limit(10).
    Select()
if err != nil {
    panic(err)
}
  1. Executing a raw SQL query:
var result []map[string]interface{}
_, err := db.Query(&result, "SELECT * FROM users WHERE id = ?", 1)
if err != nil {
    panic(err)
}

Getting Started

To start using go-pg/pg, follow these steps:

  1. Install the library:

    go get github.com/go-pg/pg/v10
    
  2. Import the package in your Go code:

    import "github.com/go-pg/pg/v10"
    
  3. Create a database connection:

    db := pg.Connect(&pg.Options{
        Addr:     "localhost:5432",
        User:     "postgres",
        Password: "password",
        Database: "mydb",
    })
    defer db.Close()
    
  4. Start using the ORM or execute queries as shown in the code examples above.

Competitor Comparisons

3,670

SQL-first Golang ORM

Pros of Bun

  • Better performance and lower memory usage
  • More flexible query building with support for subqueries and CTEs
  • Built-in support for database migrations

Cons of Bun

  • Smaller community and fewer third-party resources
  • Less mature project with potential for more frequent breaking changes
  • Steeper learning curve for developers familiar with traditional ORMs

Code Comparison

Pg:

type User struct {
    ID   int64
    Name string
}

var user User
err := db.Model(&user).Where("id = ?", 1).Select()

Bun:

type User struct {
    ID   int64  `bun:"id,pk,autoincrement"`
    Name string `bun:"name"`
}

var user User
err := db.NewSelect().Model(&user).Where("id = ?", 1).Scan(ctx)

Both Pg and Bun are Go-based PostgreSQL ORMs, but they differ in their approach and features. Pg is more established and follows a traditional ORM pattern, while Bun focuses on performance and flexibility. Bun's query builder is more powerful, allowing for complex queries, but it may require more effort to learn and use effectively. Pg, on the other hand, offers a simpler API that might be more familiar to developers coming from other ORMs. Consider your project's requirements and team expertise when choosing between these libraries.

16,124

general purpose extensions to golang's database/sql

Pros of sqlx

  • More database-agnostic, supporting multiple SQL databases (PostgreSQL, MySQL, SQLite)
  • Closer to raw SQL, offering more control and flexibility
  • Lightweight with minimal overhead

Cons of sqlx

  • Less feature-rich compared to pg's ORM-like functionality
  • Requires more manual work for complex queries and data mapping
  • Lacks some advanced PostgreSQL-specific features

Code Comparison

sqlx:

var users []User
err := sqlx.Select(db, &users, "SELECT * FROM users WHERE status = ?", "active")

pg:

var users []User
err := db.Model(&users).Where("status = ?", "active").Select()

Key Differences

  • sqlx is a thin wrapper around database/sql, while pg is a full-featured ORM
  • pg offers more PostgreSQL-specific optimizations and features
  • sqlx requires more manual SQL writing, while pg provides a query builder
  • pg includes additional features like automatic connection pooling and soft deletes

Both libraries have their strengths, with sqlx being more versatile across databases and pg offering deeper PostgreSQL integration and convenience features.

10,547

PostgreSQL driver and toolkit for Go

Pros of pgx

  • More comprehensive feature set, including support for advanced PostgreSQL features like LISTEN/NOTIFY and COPY
  • Better performance, especially for large result sets and bulk operations
  • More active development and community support

Cons of pgx

  • Steeper learning curve due to its more extensive API
  • Slightly more verbose code for simple operations
  • Less focus on ORM-like features compared to pg

Code Comparison

pg:

db := pg.Connect(&pg.Options{
    User:     "user",
    Password: "pass",
    Database: "db",
})
defer db.Close()

var users []User
err := db.Model(&users).Select()

pgx:

conn, err := pgx.Connect(context.Background(), "postgres://user:pass@localhost:5432/db")
if err != nil {
    log.Fatal(err)
}
defer conn.Close(context.Background())

var users []User
rows, _ := conn.Query(context.Background(), "SELECT * FROM users")
for rows.Next() {
    var u User
    rows.Scan(&u.ID, &u.Name)
    users = append(users, u)
}

Both pg and pgx are popular PostgreSQL drivers for Go, each with its own strengths. pg offers a more ORM-like experience with simpler syntax for basic operations, while pgx provides better performance and support for advanced PostgreSQL features at the cost of slightly more verbose code.

36,742

The fantastic ORM library for Golang, aims to be developer friendly

Pros of gorm

  • More extensive feature set, including advanced querying and associations
  • Supports multiple databases (PostgreSQL, MySQL, SQLite, SQL Server)
  • Larger community and more frequent updates

Cons of gorm

  • Steeper learning curve due to more complex API
  • Potentially slower performance for simple queries
  • Higher memory usage, especially for large datasets

Code Comparison

pg:

db := pg.Connect(&pg.Options{
    User: "user",
})
defer db.Close()

var user User
err := db.Model(&user).Where("id = ?", 1).Select()

gorm:

db, err := gorm.Open(postgres.Open("user=user"), &gorm.Config{})
if err != nil {
    panic("failed to connect database")
}

var user User
db.First(&user, 1)

Summary

pg is a lightweight, PostgreSQL-specific ORM that offers simplicity and performance for basic operations. gorm, on the other hand, provides a more feature-rich experience with support for multiple databases, making it suitable for complex applications. While pg excels in simplicity and raw performance, gorm offers more flexibility and advanced features at the cost of a steeper learning curve and potentially higher resource usage.

9,065

Pure Go Postgres driver for database/sql

Pros of pq

  • Pure Go implementation, no external dependencies
  • Widely adopted and battle-tested in production environments
  • Supports a broader range of PostgreSQL features and data types

Cons of pq

  • Requires manual SQL query writing and result scanning
  • Lacks built-in ORM functionality
  • No automatic connection pooling (requires additional setup)

Code Comparison

pg:

db := pg.Connect(&pg.Options{
    User:     "user",
    Password: "pass",
    Database: "db",
})
defer db.Close()

var users []User
err := db.Model(&users).Where("active = ?", true).Select()

pq:

db, err := sql.Open("postgres", "user=user password=pass dbname=db")
defer db.Close()

rows, err := db.Query("SELECT * FROM users WHERE active = $1", true)
defer rows.Close()
// Manual scanning of rows required

pg offers a more concise and intuitive API with built-in ORM features, while pq requires more manual handling of connections and query results. pg provides a higher level of abstraction, making it easier to work with database operations, especially for simpler use cases. However, pq offers more fine-grained control and is closer to raw SQL, which can be beneficial for complex queries or when full control over the database interaction is needed.

12,916

Generate type-safe code from SQL

Pros of sqlc

  • Generates type-safe Go code from SQL queries, reducing runtime errors
  • Supports complex queries and joins, offering more flexibility
  • Provides better performance for large-scale applications

Cons of sqlc

  • Steeper learning curve, especially for developers new to SQL
  • Requires writing raw SQL queries, which can be verbose for simple operations
  • Less abstraction from database-specific syntax

Code Comparison

sqlc:

-- name: GetAuthor :one
SELECT * FROM authors
WHERE id = $1 LIMIT 1;
author, err := queries.GetAuthor(ctx, id)

pg:

author := &Author{ID: id}
err := db.Model(author).WherePK().Select()

Key Differences

  • sqlc generates code from SQL, while pg uses a more ORM-like approach
  • sqlc offers stronger type safety, but pg provides a more intuitive API
  • pg abstracts away more SQL complexity, while sqlc gives more control over queries

Use Cases

  • Choose sqlc for complex queries and high-performance requirements
  • Opt for pg when rapid development and ease of use are priorities

Both libraries have their strengths, and the choice depends on project needs, team expertise, and performance requirements.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

PostgreSQL client and ORM for Golang

Maintenance mode

go-pg is in a maintenance mode and only critical issues are addressed. New development happens in Bun repo which offers similar functionality but works with PostgreSQL, MySQL, MariaDB, and SQLite.

Golang ORM


Go PkgGoDev Documentation Chat

Tutorials

Ecosystem

Features

Installation

go-pg supports 2 last Go versions and requires a Go version with modules support. So make sure to initialize a Go module:

go mod init github.com/my/repo

And then install go-pg (note v10 in the import; omitting it is a popular mistake):

go get github.com/go-pg/pg/v10

Quickstart

package pg_test

import (
    "fmt"

    "github.com/go-pg/pg/v10"
    "github.com/go-pg/pg/v10/orm"
)

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
    AuthorId int64
    Author   *User `pg:"rel:has-one"`
}

func (s Story) String() string {
    return fmt.Sprintf("Story<%d %s %s>", s.Id, s.Title, s.Author)
}

func ExampleDB_Model() {
    db := pg.Connect(&pg.Options{
        User: "postgres",
    })
    defer db.Close()

    err := createSchema(db)
    if err != nil {
        panic(err)
    }

    user1 := &User{
        Name:   "admin",
        Emails: []string{"admin1@admin", "admin2@admin"},
    }
    _, err = db.Model(user1).Insert()
    if err != nil {
        panic(err)
    }

    _, err = db.Model(&User{
        Name:   "root",
        Emails: []string{"root1@root", "root2@root"},
    }).Insert()
    if err != nil {
        panic(err)
    }

    story1 := &Story{
        Title:    "Cool story",
        AuthorId: user1.Id,
    }
    _, err = db.Model(story1).Insert()
    if err != nil {
        panic(err)
    }

    // Select user by primary key.
    user := &User{Id: user1.Id}
    err = db.Model(user).WherePK().Select()
    if err != nil {
        panic(err)
    }

    // Select all users.
    var users []User
    err = db.Model(&users).Select()
    if err != nil {
        panic(err)
    }

    // Select story and associated author in one query.
    story := new(Story)
    err = db.Model(story).
        Relation("Author").
        Where("story.id = ?", story1.Id).
        Select()
    if err != nil {
        panic(err)
    }

    fmt.Println(user)
    fmt.Println(users)
    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]>>
}

// createSchema creates database schema for User and Story models.
func createSchema(db *pg.DB) error {
    models := []interface{}{
        (*User)(nil),
        (*Story)(nil),
    }

    for _, model := range models {
        err := db.Model(model).CreateTable(&orm.CreateTableOptions{
            Temp: true,
        })
        if err != nil {
            return err
        }
    }
    return nil
}

See also