rasql (pronounced “rascal”) is an all-in-one SQL toolkit for Go.
It gives an application one model for schema definitions, dynamic queries, static queries, result decoding, and database inspection. Every statement it produces is parameterized, so values travel as bound arguments and never as SQL text.
rasql comes in two layers that share one query and execution model.
- The core layer describes tables, builds SQL, compiles templates, inspects databases, and applies migrations.
- The ORM layer adds generated sources, projections, decoders, mutation plans, and graph plans. Every workflow executes through
rasql.Executorand the same result terminals.
Most applications start with the ORM layer. Getting started installs the toolkit, describes a table, and runs a first query end to end, and Querying says which layer a given task calls for.
- DDL migrations. Run checked-in SQL migration directories in order with
rasql migrate apply, revert them withrasql migrate revert, and generate a PostgreSQL, MySQL, or SQLite migration from desired-schema sources when that helps. A migration is recorded only once every one of its sources has succeeded, so one that fails part way through stays pending and runs again. See Migrations. - Query builder. The
querypackage builds a dialect-neutral statement and validates it, andrenderturns that statement into SQL text with its arguments in placeholder order. Both packages import onlyschemaanddialect, so this layer runs with no database handle and no Go row type. See The SQL builder. - ORM. Run
rasql codegen generateagainst a database to write typed rows, sources, projections, mutation builders, graph descriptors, and static queries as checked-in Go. Build reads withrasql.Select, writes with mutation plans, and consume results withRows,All,One, orMaybe. Seerasql codegen, Typed queries, and Writing rows. - Runtime-selected results. Build a
ResultSchemaat run time and pass it toDynamicProjection, then use that projection withSelectorNative. The standard result terminals return ordered row values without a second execution API. - Static query templates. Compile SQL text with named binds into parameterized statements. See Named SQL.
- Schema description and inspection. Write table definitions as Go code, or read them back from a live database. See Schemas.
- PostgreSQL, MySQL, and SQLite. Engine profiles make supported syntax and limits explicit. The conformance suite records the portable cases exercised for each engine.
rasql requires Go 1.26 or newer. It builds on database/sql, so an application imports the driver it wants where it opens the connection.
go get github.com/lestrrat-go/rasqlThe generator is a separate command, installed and run from the module root whenever the source database changes:
go run github.com/lestrrat-go/rasql/cmd/rasql codegen generate -dsn "$DATABASE_URL"It reads the live metadata and writes the store package. The settings that stay the same from run to run live in a checked-in rasql.json, which rasql codegen covers, and The generated store shows the files a run leaves behind.
The Taskboard sample is an HTTP application on PostgreSQL, built on checked-in migrations and a generated store. Its page shows typed descriptors, a joined read, an insert, an update, and a compiled SQL query in one small application. It is a module of its own, example.com/taskboard, so it reaches rasql only through the public API a real project has.
Its nine-chapter walkthrough is how the code got there. It settles the schema against a running PostgreSQL server, captures it into a migration, generates the Go, writes the application on top, and then changes the schema and follows the compiler through what breaks.
Running it needs a PostgreSQL server and a database on it:
cd sample/taskboard
export TASKBOARD_DSN='postgres://rasql:rasql@127.0.0.1:5432/taskboard?sslmode=disable'
./scripts/migrate.sh apply
go run ./cmd/taskboardscripts/migrate.sh applies the migrations with rasql migrate apply, and the application then serves the page over whatever rows the database holds. Open http://127.0.0.1:8080/ in another terminal. The sample's README covers the rest, including the two rows to insert before the add form has a project and an owner to offer.
The documentation index groups these pages by layer: the core layer builds and runs SQL with no Go row type, and the ORM layer generates a store package and reads and writes Go values through it.
| Page | Covers |
|---|---|
| Getting started | Installing, creating a DB, and running a first query. |
| Querying | Portable queries, native SQL, projections, and result terminals. |
| Core layer | |
| Schemas | Describing tables in Go and reading them back from a live database. |
| The SQL builder | Building and rendering a statement through query and render, with a reference for every constructor and predicate. |
| Write statements | Building inserts, updates, deletes, and upserts, and reading a RETURNING clause. |
| The database handle | Running a rendered statement, installing hooks, and starting a transaction. |
| Dynamic results | Decoding a runtime-selected result schema through the canonical query API. |
| Named SQL | Compiling SQL text with named binds into parameterized statements. |
| Migrations | Applying ordered DDL migrations, and reverting them. |
| Inspection-only facts | Reference for the facts inspection reads that rasql cannot write back as DDL. |
| ORM layer | |
rasql codegen |
Running the generator and configuring it with rasql.json. |
| The generated store | The row types, table types, column accessors, and static query functions it writes. |
| Typed queries | Sources, typed expressions, projections, joins, and result terminals. |
| Writing rows | Create, patch, delete, native, and batch mutation plans. |
The API reference lives at pkg.go.dev. Each code block that links to a source file is a runnable Go example from examples/, verified by go test.
Most applications only import the root rasql package plus dialect and schema. The rest are building blocks the root package uses on their behalf.
| Package | Responsibility |
|---|---|
rasql |
Defines typed queries, projections, mutation and graph plans, executors, and result terminals. |
schema |
Describes tables, columns, indexes, constraints, and logical types. |
dialect |
Decides identifier quoting, placeholders, type mapping, and syntax support. |
query |
Represents dialect-neutral statements and expressions, with validation. |
render |
Turns a validated query into SQL text and an ordered argument list. |
inspect |
Reads live database metadata into schema descriptors. |
catalog |
Reads a whole live catalog in one transaction and applies table selection. |
migrate |
Plans, executes, and reverts DDL migrations with durable history. |
namedsql, generate |
Compile templates and descriptors into deterministic Go source. |
cmd/rasql |
Scaffolds the generator program and applies migrations, as rasql codegen and rasql migrate. |
cmd/rasqlgen, cmd/rasqlmigrate |
Accept the same commands as the unified rasql command, under their own names. |
See DESIGN.md for the architecture and the reasoning behind these boundaries.
See CONTRIBUTING.md for the local development workflow, including running the live-database tests.