When you start a new project in Go, you probably always ask yourself about the data access layer. Use the generic database/sql
interface and write queries by hand or use an ORM package, or tools to help generate queries? Which database driver to use? What packages to use to make your workflow fast and smooth? In this post we will try to review the best available drivers and ORM packages for the PostgreSQL database. Unfortunately, there are a lot of them, and they are all good enough, so the choice will not be easy, and you have to decide what is the most important for you 😉.
Drivers
1. pgx
Recommended driver for a new project, actively maintained and developed. Low-level, fast, and performant. It consists of two components: driver and toolkit. The driver is compatible with the database/sql
interface, while the toolkit contains PostgreSQL-specific features and functionalities that make your work easier, such as mapping between PostgreSQL and Go.
Github: https://github.com/jackc/pgx
Package documentation: pgx
2. pq
Historically the most popular PostgreSQL driver for Go. Well tested and used in many existing projects. Currently only in the maintenance mode. As the authors themselves say:
“For users that require new features or reliable resolution of reported bugs, we recommend using pgx which is under active development.” – pq maintainers
However, if you are looking for a battle-tested and stable driver for Go, the pq
is a great choice.
Github: https://github.com/lib/pq
Package documentation: pg
ORMs
1. GORM
One of the most popular ORM packages in Go, whose the main goal is to be developer-friendly. Officially supports PostgreSQL, MySQL, SQLite, and MSSQL. It is actively developed, has great documentation, and many features, like:
- Struct - Table mapping support
- Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism, Single-table inheritance)
- Hooks (Before/After Create/Save/Update/Delete/Find)
- Eager loading with
Preload
,Joins
- Transactions, nested transactions, Save Point, RollbackTo to Saved Point
- Context, prepared statement mode, DryRun mode
- Batch Insert, FindInBatches, Find/Create with map, CRUD with SQL Expr and Context Valuer
- SQL Builder, Upsert, Locking, Optimizer/Index/Comment Hints, Named Argument, SubQuery
- Composite Primary Key, Indexes, Constraints
- Auto migrations
- and many more
Website: https://gorm.io
Github: https://github.com/go-gorm/gorm
Package documentation: GORM
2. Bun
Bun
is a SQL-first ORM that provides an ORM-like experience using good old SQL. It supports PostgreSQL, MySQL, MariaDB, MSSQL, and SQLite. Great documentation and essential features, useful in everyday work are its strong points:
- Bulk inserts
- Bulk updates
- Bulk deletes
- Fixtures - load initial data into a database for testing or demonstration purposes using YAML files
- Migrations
- Soft deletes
Website: https://bun.uptrace.dev
Github: https://github.com/uptrace/bun
Package documentation: Bun
3. ent
An entity framework for Go. It is the ORM developed by Facebook focusing on graph-based data models. The schema is defined as a graph structure in Go code, from which the model and operations are generated using code generation. It supports PostgreSQL, MySQL, MariaDB, TiDB, SQLite, and Gremlin.
Website: https://entgo.io
Github: https://github.com/ent/ent
Package documentation: ent
4. upper/db
A data access layer made for productivity. API is compatible with SQL and NoSQL databases like PostgreSQL, MySQL, MSSQL, CockroachDB, MongoDB, QL, and SQLite. It provides an agnostic API focused on working with collections of items, a SQL builder for more direct access to the database, and an ORM-like layer for mapping between a struct and a database table and working with the database in a more ORM-like style. Some features:
- Struct - Table Mapping Support
- Search and delimitation of result sets
- Limit-offset pagination (page numbers)
- Cursor-based pagination (previous and next)
- Transactions support
Website: https://upper.io
Github: https://github.com/upper/db
Package documentation: upper/db
5. XORM
Simple and powerful GORM alternative supporting PostgreSQL, MySQL, SQLite, MSSQL, MariaDB, TiDB, CockroachDB, and Oracle. Some of the features:
- Struct - Table mapping support
- Transactions support
- Synchronization of database schema
- Query cache
- Database Reverse - tool that generates code from the database schema
- Simple cascade loading
- Optimistic Locking support
- SQL Builder
- and many more
Website: https://xorm.io/
Gitea: https://gitea.com/xorm/xorm
Package documentation: XORM
6. POP
It is part of the Buffalo Go web framework, deeply integrated, and recommended when using Buffalo. But can also be used as a stand-alone data access layer. POP follows conventions influenced by the ActiveRecord Ruby gem making it easy to do CRUD operations with basic ORM functionality, run migrations, and build/execute queries. It supports PostgreSQL, CockroachDB, MySQL, and SQLite databases.
Website: https://gobuffalo.io/documentation/database/pop
Github: https://github.com/gobuffalo/pop
Package documentation: POP
7. REL
REL is a modern ORM-ish data access layer for layered architecture. It is built with testability in mind and comes with its custom test library. It supports PostgreSQL, MySQL, MSSQL, and SQLite. Features:
- Testable repository
- Nested transactions
- Query builder
- Eager loading support
- Composite Primary Key
- Soft deletes
- Pagination
- Schema Migration
Website: https://go-rel.github.io
Github: https://github.com/go-rel/rel
Package documentation: REL
8. Beego ORM
This ORM is part of the Beego web framework. Heavily influenced by Django ORM and SQLAlchemy. It works with PostgreSQL, MySQL, and SQLite databases. The main features are: easy to use CRUD operations, Struct - Table mapping, raw SQL support and query builder, auto joins, transactions support.
Website: https://beego.vip/docs/mvc/model/overview.md
Github: https://github.com/beego/beego/tree/master/client/orm
Package documentation: Beego ORM