sq
is a type-safe query builder and data mapper for Go. It supports the SQLite, Postgres and MySQL dialects. Among its features are:
- Type-safety
- Every table gets a struct type
- Every column gets a struct field
- You no longer have to hardcode tables and columns as raw strings (even ORMs are guilty of this)
- Declarative schema as code (provided by the
ddl
companion package)- The database can be the source of truth: setup your database first, then code generate the table structs from the database.
- -OR- The table structs can be the source of truth: define your tables declaratively as code (i.e. structs), then generate the necessary DDL needed to migrate the database to your desired state.
- What is supported: schemas, extensions, enums, functions, tables, columns, constraints, indexes, (materialized) views, triggers
- Able to utilize Go generics for data fetching
- Data fetching uses callback mapper functions
- FetchOne/FetchSlice are generic fetch functions that return whatever the callback mapper function returns
- As convenient as an ORM, without actually using an ORM
- Emulates each SQL dialect faithfully
sq
does not attempt to abstract all SQL dialects into one.- Each dialect has its own query builder and can make full use of dialect-specific features.
- This does not mean that queries are not portable: queries are as portable as the SQL that you write
- If you stick with a common subset of SQL, queries generated by a Postgres query builder can be used in SQLite/MySQL databases as well (by simply changing the
Dialect
field)
- Application-side Row Level Security (i.e. multitenancy support)
- Queries can be primed with a query context -- a
map[string]interface{}
that can contain anything you want - Based on this query context, tables participating in the query that implement the PredicateInjector interface can inject additional predicates to exclude rows from a SELECT, UPDATE or DELETE.
- This emulates a huge part of Postgres' Row Level Security feature, but more importantly it plays well with
database/sql
's connection pooling since variables are set per query and not per session. - Plus, SQLite and MySQL get Row Level Security for free!
- Queries can be primed with a query context -- a
- sq ❤ SQL
- Multiple schemas, Generated Columns, Full Text Search, JSON, Collations are all par for the course
sq
covers the full lifecycle of SQL in the application: from database definition, to query generation, to data mapping