CLI tool
xo/dbtpl avatar
xo/dbtpl

xo/dbtpl: generating Go models from a live database schema

Command line tool to generate idiomatic Go code for SQL databases supporting PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server

3,897 stars336 forksGoMIT

At a glance

What is it?
dbtpl inspects PostgreSQL, MySQL, SQLite, Oracle and Microsoft SQL Server schemas and renders Go code through templates. It is a code generator for people who want their database to stay the source of truth, not an ORM runtime.
Who is it for?
Adopt dbtpl when your schema is authoritative and you want Go types, JSON/YAML definitions or Graphviz diagrams produced from it, and when you accept that the README describes the output as production quality but explicitly not a silver bullet that removes manual SQL and Go authoring.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 23 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem dbtpl solves is schema drift, not query writing

Every Go service that talks to SQL eventually grows a second, hand-written description of the database: structs with db tags, scan helpers, enum constants. That description is correct on the day it is written. The schema keeps moving. dbtpl takes the other direction. It connects to a live database, reads its metadata, and emits Go source files from that metadata, so the generated types track the schema instead of a memory of it. The README frames the tool as inspecting and generating templated code from a database schema or a custom query, and it names four output families: model code, schema creation scripts, JSON and YAML definitions, and Graphviz diagrams. That last set matters more than it looks. A tool that only emits structs is a convenience. A tool that can also dump a schema as data and as a diagram is a way to diff two environments without reading DDL by eye. The intended audience is a Go team that already owns its SQL and does not want an ORM deciding when to issue statements. The README is explicit that the generator is not meant to remove manual SQL or Go authoring, which is a fair description of the boundary: dbtpl writes the repetitive layer, you write the interesting one.

Schema mode: introspection queries plus Go templates

The mechanism is stated plainly in the README. In schema mode dbtpl connects to the database and generates code using Go templates. It uses database metadata and SQL introspection queries to discover the types and relationships in a schema, then applies a base or customized set of Go templates against what it found. The repository layout matches that description: a loader/ directory for the introspection side, a templates/ directory for the rendering side, and types/ for the shared model of what was discovered. There is also an internal/ directory and a cmd/ directory, so the CLI is a thin layer over those packages. The supported set is tables, enums, stored procedures and custom SQL queries, across PostgreSQL, MySQL, Oracle, Microsoft SQL Server and SQLite3. The feature matrix is where the abstraction leaks. Models, primary keys, foreign keys, indexes, stored procedures and functions are marked as supported on all five engines. ENUM types are marked for PostgreSQL and MySQL only. Custom types are marked for PostgreSQL only. If your schema leans on Oracle object types or SQL Server user-defined types, the generated output will not reflect them, and you should treat the matrix as the contract rather than the marketing line about five databases. Query mode is the second path: dbtpl parses a query you supply, finds the related tables in the database, and generates code from Go templates so the result is type safe. The README's example query shows the placeholder syntax, %%authorID int%% and %%limit int%%, which is how parameters are declared inside the SQL text.

Installing dbtpl and generating your first models

The README offers five install routes: a downloaded release archive, Homebrew, the Arch Linux AUR, Scoop on Windows, and go install. The Go route is the shortest if you already have a toolchain. The module path in go.mod is github.com/xo/dbtpl, and the README's install command points at the same path.

bash
go install github.com/xo/dbtpl@latest

After that, the quickstart makes an output directory and points dbtpl at a PostgreSQL DSN. The default output folder is models.

bash
mkdir -p models
dbtpl schema postgres://user:pass@host/dbname

You should end up with Go files under models/ that describe the tables dbtpl discovered. The quickstart then compiles them, which is the check worth running before you look at anything else, because a generator that emits code your compiler rejects is worse than no generator.

bash
go build ./models/

Two variations are worth knowing on day one. A custom template directory is passed with --src, and the output directory with -o, as in the README's Microsoft SQL example.

bash
mkdir -p mssqlmodels
dbtpl schema mssql://user:pass@host/dbname -o mssqlmodels --src custom/templates

The query subcommand takes a DSN and reads SQL from standard input, terminated by the ENDSQL marker. The flags in the README's example are -M, -B, -2 and -T AuthorResult, with -T naming the result type. The same command block lists -s for schema name, -t for template type (createdb, dot, go, json, yaml; default go) and -f for the file extension suffix on generated files. Those three flags are how you get the non-Go outputs the README mentions.

Where dbtpl is the wrong tool

The first limitation is in the README itself, and it is worth quoting rather than paraphrasing: the generated code is described as production quality, but the project states it is not the goal nor the intention for dbtpl to be a silver bullet, nor to completely eliminate the manual authoring of SQL and Go code. Read that as a design statement. If your requirement is that nobody on the team writes SQL by hand, dbtpl does not meet it and does not claim to. The second limitation is language. The README says dbtpl only supports Go at the moment, and that support for other languages is possible but not currently planned. A polyglot team that wants one generator for a Go service and a Python worker will not get it here. The third is the feature matrix. ENUM types are absent for Oracle, SQL Server and SQLite; custom types are absent for everything except PostgreSQL. A schema that depends on those constructs will produce output that silently omits them, which is the failure mode to watch for: not an error, but a gap. The fourth is a release cadence observation rather than a defect. The most recent release listed is v1.0.2 from 2024-05-24, and v1.0.1 before that in 2023-12-25, while the last push to the repository was on 2026-09-08. The code on main and the newest tagged artifact are therefore different things, and installing @latest from the Go module proxy may not give you the same tree you read on the default branch. Pin a version if you need reproducibility.

dbtpl against sqlc and SQLBoiler

The related searches around this project are dominated by other Go database tools, which is a fair signal about how people arrive here. sqlc and SQLBoiler take different positions on the same problem. SQLBoiler is an ORM generator: it reads your schema and produces a full runtime layer with query building, relationship loading and hooks, so the generated code is something your application calls into at runtime. dbtpl's README does not describe a runtime query builder or relationship loading; it describes template rendering from introspected metadata, with the templates directory as the customization point. That is a narrower promise and a smaller dependency surface. sqlc works from SQL files you write, compiling annotated queries into Go functions, so the SQL is the input and the schema check happens at generation time. dbtpl's query mode is closer to that idea, but the README presents it as parsing a query and finding related tables for type safety, not as a query-file compiler with a migration model. The practical difference: if you want generated functions for every query you have written, sqlc's model fits better. If you want one pass over the schema that yields models plus JSON, YAML and Graphviz views of the same database, dbtpl covers ground the other two do not. The searches also surface Ent and generic Go query builders, which are runtime libraries rather than generators; they solve query construction, not schema-to-type synchronization, and picking one of those is not an alternative to dbtpl so much as a different layer.

Licence, dependencies and what an upgrade costs

dbtpl is MIT licensed, which is permissive and imposes no copyleft obligation on generated output; the LICENSE file sits at the repository root. That said, the licence of the generator says nothing about the licences of the packages it pulls in, and go.mod lists a substantial dependency set: database drivers for MySQL, PostgreSQL, SQLite and SQL Server plus a pure-Go Oracle driver, the sprig template function library, gofumpt and golang.org/x/tools for formatting generated source, and yaegi, an embedded Go interpreter. The presence of gofumpt and x/tools in the direct requirements is consistent with the README's claim of idiomatic output: the generator formats what it emits rather than leaving that to you. The upgrade cost is dominated by two things. Templates are the customization surface, so any local template directory passed with --src becomes code you maintain against upstream template changes. And generated files are checked in, which means every regeneration shows up as a diff in review. The version gap between the tagged releases and main makes that diff larger than it needs to be if you switch between the two. Decide early whether you regenerate in CI or commit the output, because the answer changes how much a schema change costs the team.

Editorial conclusion

Adopt dbtpl when your schema is authoritative and you want Go types, JSON/YAML definitions or Graphviz diagrams produced from it, and when you accept that the README describes the output as production quality but explicitly not a silver bullet that removes manual SQL and Go authoring. Do not adopt it if you need a runtime ORM with lazy loading and query building, or if you need generated code in a language other than Go, which the README says is possible but not currently planned. Before committing, verify the feature matrix entry for your database (ENUM types are PostgreSQL and MySQL only, custom types are PostgreSQL only), check that the version tag you install matches the code in cmd/ and templates/, and run go build against the generated output as the quickstart does.

Frequently asked questions

Which databases does dbtpl support for Go code generation?

The README lists PostgreSQL, MySQL, Oracle, Microsoft SQL Server and SQLite3, and the feature matrix marks models, primary keys, foreign keys, indexes, stored procedures and functions as supported on all five. ENUM types are marked only for PostgreSQL and MySQL, and custom types only for PostgreSQL.

Can dbtpl generate code in a language other than Go?

No. The README states that dbtpl only supports Go at the moment, and that support for other languages is possible but not currently planned.

How do I install dbtpl?

The README gives five routes: a downloaded release archive, Homebrew via the xo/xo tap, the Arch Linux AUR, Scoop on Windows, and go install github.com/xo/dbtpl@latest. The Go route requires a Go toolchain matching the module's go directive.

What template types can dbtpl render besides Go models?

The query subcommand's -t flag accepts createdb, dot, go, json and yaml, with go as the default. The createdb and dot options correspond to the schema creation scripts and Graphviz diagrams the README mentions.

Does dbtpl replace hand-written SQL and Go code?

The README explicitly says it is not the goal nor the intention for dbtpl to be a silver bullet, nor to completely eliminate the manual authoring of SQL and Go code, even though it describes the generated code as production quality.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. xo/dbtpl on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/xo-dbtpl.svg)](https://hysenlabs.com/projects/xo-dbtpl)