tbls is a free, open source databases project written in Go and released under MIT. It has 4,373 GitHub stars, 216 forks and 55 open issues, and was last pushed yesterday. On this registry it ranks #163 of 206 tracked projects in Databases, with 5 head-to-head comparisons available. It gained 20 stars over the last 30 tracked days.

What is tbls?

tbls is an MIT-licensed, Go-written command line tool that automatically documents a database schema as Markdown and other formats, aimed at developers, data engineers, and platform teams who want schema documentation generated, diffed, and linted inside continuous integration instead of maintained by hand.

What it is

tbls (pronounced /ˈteɪbl̩z/) is a CI-friendly database documentation tool written in Go. It connects to a database through a DSN and generates a document set describing the schema, including tables, columns, comments, and relations, in GitHub Flavored Markdown and several other output formats. Configuration lives in a .tbls.yml or tbls.yml file inside the repository, where the datasource DSN and the output location are declared; docPath defaults to dbdoc.

The concrete problem it solves is that hand-written schema documentation drifts out of date as migrations land. tbls replaces manual upkeep of schema documents by generating them from the live database and then letting CI verify them: tbls diff compares a database against the existing document or against another database, tbls lint works as a linter for the database itself, and document coverage can be measured so missing table and column descriptions become visible. Because it ships as a single binary and is also distributed as a Docker image and a GitHub Action, the whole check fits into an ordinary pipeline in the Infrastructure & Operations / Databases space.

Key capabilities

  • Generate database documentation automatically in GFM format, with additional output formats including Markdown, Excel, and Mermaid and PlantUML ER diagrams.
  • Document many datasources: PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, BigQuery, Amazon DynamoDB, Amazon Redshift, Snowflake, and Google Cloud Spanner.
  • Diff a database against its documentation, or one database against another, using tbls diff.
  • Lint the database with tbls lint and measure document coverage.
  • Define relations, viewpoints, a dictionary, comments, labels, and table filters in .tbls.yml.
  • Personalize output with custom templates, expand environment variables in configuration, and require a specific version of tbls.
  • Run as a single binary, installed through Homebrew, MacPorts, a deb or RPM package, aqua, go install github.com/k1LoW/tbls@latest, or the ghcr.io/k1low/tbls Docker image.

Who uses it and how

  • Teams that keep schema documentation in the repository run tbls doc and commit the generated files under a docPath such as doc/schema.
  • CI pipelines run tbls doc on push to main through the k1low/setup-tbls@v1 Action, so the build surfaces documentation drift.
  • Docker users run docker run --rm -v $PWD:/work -w /work ghcr.io/k1low/tbls doc where installing Go or a system package is unwanted.
  • Organizations with several engines point one tool at PostgreSQL, MySQL, BigQuery, and Snowflake schemas instead of keeping per-engine scripts.

Getting started

Install with brew install tbls, a deb or RPM package, MacPorts, aqua, or go install github.com/k1LoW/tbls@latest, or pull ghcr.io/k1low/tbls:latest. Then add a .tbls.yml containing a dsn and run tbls doc postgres://dbuser:dbpass@hostname:5432/dbname.

How it compares

The facts provided name no other database documentation tool, so this page stands alone in this registry. On its own facts, the distinguishing property is the MIT licence combined with a single Go binary that doubles as documentation generator, differ, and linter rather than a hosted service.

When to use it — and when not to

tbls needs a reachable database: the DSN is supplied through .tbls.yml or the command line, so in CI the target database must run as a service with credentials available, which environment-variable expansion support eases but does not remove. A team that wants a hosted, always-on schema browser, or one that runs no CI at all, should not pick it. Note also that the project carries 55 open issues, so expect some rough edges around individual datasources.

project readme (upstream, from github) — read inline


tbls

Build Status GitHub release Go Report Card Coverage Code to Test Ratio Test Execution Time

tbls (pronounced /ˈteɪbl̩z/) is a CI-Friendly tool to document a database, written in Go.

Key features of tbls are:

Table of Contents


Quick Start

Document a database with one command.

$ tbls doc postgres://dbuser:dbpass@hostname:5432/dbname

Using docker image.

$ docker run --rm -v $PWD:/work -w /work ghcr.io/k1low/tbls doc postgres://dbuser:dbpass@hostname:5432/dbname

Install

deb:

$ export TBLS_VERSION=X.X.X
$ curl -o tbls.deb -L https://github.com/k1LoW/tbls/releases/download/v$TBLS_VERSION/tbls_$TBLS_VERSION-1_amd64.deb
$ dpkg -i tbls.deb

RPM:

$ export TBLS_VERSION=X.X.X
$ yum install https://github.com/k1LoW/tbls/releases/download/v$TBLS_VERSION/tbls_$TBLS_VERSION-1_amd64.rpm

Homebrew:

$ brew install tbls

MacPorts:

$ sudo port install tbls

aqua:

$ aqua g -i k1LoW/tbls

Manually:

Download binary from releases page

go install:

$ go install github.com/k1LoW/tbls@latest

Docker:

$ docker pull ghcr.io/k1low/tbls:latest

On GitHub Actions:

# .github/workflows/doc.yml
name: Document

on:
  push:
    branches:
      - main

jobs:
  doc:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout .tbls.yml
        uses: actions/checkout@v3
      -
        uses: k1low/setup-tbls@v1
      -
        name: Run tbls for generate database document
        run: tbls doc

:octocat: A GitHub Action for tbls is here.

Temporary:

$ source <(curl https://raw.githubusercontent.com/k1LoW/tbls/main/use)
$ curl -sL https://raw.githubusercontent.com/k1LoW/tbls/main/use > /tmp/use-tbls.tmp && . /tmp/use-tbls.tmp

Getting Started

Document a database

Add .tbls.yml (or tbls.yml) file to your repository.

# .tbls.yml

# DSN (Database Source Name) to connect database
dsn: postgres://dbuser:dbpass@localhost:5432/dbname

# Path to generate document
# Default is `dbdoc`
docPath: doc/schema

Notice: If you are using a symbol such as # **Notice:**tbls diff` shows the difference Markdown documents only.

Re-generating database documentation

Existing documentation can re-generated using either --force or --rm-dist flag.

--force forces overwrite of the existing documents. It does not, however, remove files of removed tables.

$ tbls doc --force

--rm-dist removes files in docPath before generating the documents.

$ tbls doc --rm-dist

Lint a database

Add linting rule to .tbls.yml following

# .tbls.yml
lint:
  requireColumnComment:
    enabled: true
    exclude:
      - id
      - created
      - updated
  columnCount:
    enabled: true
    max: 10

Run tbls lint to check the database according to lint: rules

$ tbls lint
users.username: column comment required.
users.password: column comment required.
users.phone_number: column comment required.
posts.user_id: column comment required.
posts.title: column comment required.
posts.labels: column comment required.
comments.post_id: column comment required.
comment_stars.user_id: column comment required.
post_comments.comment: column comment required.
posts: too many columns. [12/10]
comments: too many columns. [11/10]

11 detected

Measure document coverage

tbls coverage measure and show document coverage (description, comments).

$ tbls coverage
Table                       Coverage
All tables                  16.1%
 public.users               20%
 public.user_options        37.5%
 public.posts               35.3%
 public.comments            14.3%
 public.comment_stars       0%
 public.logs                12.5%
 public.post_comments       87.5%
 public.post_comment_stars  0%
 public.CamelizeTable       0%
 public.hyphen-table        0%
 administrator.blogs        0%
 backup.blogs               0%
 backup.blog_options        0%
 time.bar                   0%
 time.hyphenated-table      0%
 time.referencing           0%

Continuous Integration

Continuous integration using tbls.

  1. Commit the document using tbls doc.
  2. Update the database schema in the development cycle.
  3. Check for document updates by running tbls diff or tbls lint in CI.
  4. Return to 1.

Example: Travis CI

# .travis.yml
language: go

install:
  - source <(curl -sL https://raw.githubusercontent.com/k1LoW/tbls/main/use)
script:
  - tbls diff
  - tbls lint

Tips: If your CI based on Debian/Ubuntu (/bin/sh -> dash), you can use the following install command curl -sL https://raw.githubusercontent.com/k1LoW/tbls/main/use > use-tbls.tmp && . ./use-tbls.tmp && rm ./use-tbls.tmp

Tips: If the order of the columns does not match, you can use the --sort option.

Configuration

Name

name: is used to specify the database name of the document.

# .tbls.yml
name: mydatabase

Description

desc: is used to specify the database description.

# .tbls.yml
desc: This is My Database

Labels

labels: is used to label the database or tables.

label database:

# .tbls.yml
labels:
  - cmdb
  - analytics

label tables:

# .tbls.yml
comments:
  -
    table: users
    labels:
      - user
      - privacy data

label columns:

# .tbls.yml
comments:
  -
    table: users
    columnLabels:
      email:
        - secure
        - encrypted

DSN

dsn: (Data Source Name) is used to connect to database.

# .tbls.yml
dsn: my://dbuser:dbpass@hostname:3306/dbname
SSL/TLS

For PostgreSQL, MySQL, MariaDB and Microsoft SQL Server, the tls: section of dsn: configures SSL/TLS using certificate files:

# .tbls.yml
dsn:
  url: my://dbuser:dbpass@hostname:3306/dbname
  tls:
    ca: /path/to/ca.pem
    cert: /path/to/client-cert.pem
    key: /path/to/client-key.pem
    verify: identity
  • ca verifies the server certificate chain without hostname verification (like mysql --ssl-mode=VERIFY_CA).
  • verify: identity also verifies the hostname (like mysql --ssl-mode=VERIFY_IDENTITY).
  • cert and key present a client certificate, and must be set together. Without ca or verify: identity the connection is encrypted but the server is not verified.
  • Empty values are treated as absent, so settings like ca: ${MYSQL_SSL_CA} work unchanged when the environment variables are not set. Paired settings (cert/key) must be set or unset together.
  • Native TLS DSN parameters that contradict these settings (e.g. sslmode=disable, encrypt=disable, trustservercertificate=true, tls=preferred) are rejected with an error instead of being silently overridden. tls=true keeps full verification, and tls=skip-verify is upgraded to the requested verification level.
Support Datasource

tbls supports the following databases/datasources.

PostgreSQL:

# .tbls.yml
dsn: postgres://dbuser:dbpass@hostname:5432/dbname
# .tbls.yml
dsn: pg://dbuser:dbpass@hostname:5432/dbname

When you want to disable SSL mode, add "?sslmode=disable" For example:

dsn: pg://dbuser:dbpass@hostname:5432/dbname?sslmode=disable

The dsn.tls settings map to sslrootcert, sslcert and sslkey, with sslmode=verify-ca (or sslmode=verify-full when verify: identity is set). An explicit verifying sslmode (require, verify-ca, verify-full) is kept. Certificate paths containing spaces are not supported.

MySQL:

# .tbls.yml
dsn: mysql://dbuser:dbpass@hostname:3306/dbname
# .tbls.yml
dsn: my://dbuser:dbpass@hostname:3306/dbname

When you want to hide AUTO_INCREMENT clause on the table definitions, add "?hide_auto_increment". For example:

dsn: my://dbuser:dbpass@hostname:3306/dbname?hide_auto_increment

Each --ssl-mode of the mysql client maps to a DSN parameter or dsn.tls settings (see the SSL/TLS section) as follows:

--ssl-mode tbls configuration
DISABLED ?tls=false
PREFERRED ?tls=preferred
REQUIRED ?tls=skip-verify
VERIFY_CA tls: with ca: /path/to/ca.pem
VERIFY_IDENTITY tls: with ca: /path/to/ca.pem and verify: identity

MariaDB:

# .tbls.yml
dsn: mariadb://dbuser:dbpass@hostname:3306/dbname
# .tbls.yml
dsn: maria://dbuser:dbpass@hostname:3306/dbname

SQLite:

# .tbls.yml
dsn: sqlite:///path/to/dbname.db
# .tbls.yml
dsn: sq:///path/to/dbname.db

BigQuery:

# .tbls.yml
dsn: bigquery://project-id/dataset-id?creds=/path/to/google_application_credentials.json
# .tbls.yml
dsn: bq://project-id/dataset-id?creds=/path/to/google_application_credentials.json

To set GOOGLE_APPLICATION_CREDENTIALS environment variable, you can use

  1. export GOOGLE_APPLICATION_CREDENTIALS or export GOOGLE_APPLICATION_CREDENTIALS_JSON
  2. Add query to DSN
    • ?google_application_credentials=/path/to/client_secrets.json
    • ?credentials=/path/to/client_secrets.json
    • ?creds=/path/to/client_secrets.json

Required permissions: bigquery.datasets.get bigquery.tables.get bigquery.tables.list

Also, you can use impersonate service account using environment variables below.

  • GOOGLE_IMPERSONATE_SERVICE_ACCOUNT: Email of service account
  • GOOGLE_IMPERSONATE_SERVICE_ACCOUNT_LIFETIME: You can use impersonate service account within this lifetime. This value must be readable from https://github.com/k1LoW/duration .

Cloud Spanner:

# .tbls.yml
dsn: spanner://project-id/instance-id/dbname?creds=/path/to/google_application_credentials.json

To set GOOGLE_APPLICATION_CREDENTIALS environment variable, you can use

  1. export GOOGLE_APPLICATION_CREDENTIALS or export GOOGLE_APPLICATION_CREDENTIALS_JSON
  2. Add query to DSN
    • ?google_application_credentials=/path/to/client_secrets.json
    • ?credentials=/path/to/client_secrets.json
    • ?creds=/path/to/client_secrets.json

Also, you can use impersonate service account using environment variables below.

  • GOOGLE_IMPERSONATE_SERVICE_ACCOUNT: Email of service account
  • GOOGLE_IMPERSONATE_SERVICE_ACCOUNT_LIFETIME: You can use impersonate service account within this lifetime. This value must be readable from https://github.com/k1LoW/duration .

Amazon Redshift:

# .tbls.yml
dsn: redshift://dbuser:dbpass@hostname:5432/dbname
# .tbls.yml
dsn: rs://dbuser:dbpass@hostname:5432/dbname

Microsoft SQL Server:

# .tbls.yml
dsn: mssql://DbUser:SQLServer-DbPassw0rd@hostname:1433/testdb
# .tbls.yml
dsn: sqlserver://DbUser:SQLServer-DbPassw0rd@hostname:1433/testdb
# .tbls.yml
dsn: ms://DbUser:SQLServer-DbPassw0rd@localhost:1433/testdb

SQL Server 2017 or later with a database compatibility level of 110 or higher is required. Schema introspection uses STRING_AGG, which is unavailable on SQL Server 2016 and earlier, and its WITHIN GROUP (ORDER BY ...) clause needs compatibility level 110+. A database migrated onto a newer server but left at level 100 fails with Incorrect syntax near '('; raise it with ALTER DATABASE SET COMPATIBILITY_LEVEL = 110 (or higher).

Azure SQL / Microsoft Fabric Warehouse (Experimental):

Azure AD Service Principal authentication (credentials in userinfo):

# .tbls.yml
dsn: azuresql://<client-id>@<tenant-id>:<client-secret>@myworkspace.datawarehouse.fabric.microsoft.com/mydb

Azure AD Default authentication (picks up AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, Azure CLI, or Managed Identity):

# .tbls.yml
dsn: azuresql://myworkspace.datawarehouse.fabric.microsoft.com/mydb

Supported DSN formats and parameters:

  • Database name can be provided in the URL path (/mydb) or via the database query parameter (?database=mydb).
  • fedauth: authentication type. If omitted, defaults to ActiveDirectoryServicePrincipal when credentials are provided in userinfo, or ActiveDirectoryDefault otherwise.
  • Tenant ID in userinfo is optional (azuresql://:@host/mydb), resolved from the server if omitted.
  • Other supported fedauth modes include ActiveDirectoryPassword, ActiveDirectoryMSI, etc.

See also: https://github.com/microsoft/go-mssqldb

The dsn.tls.ca setting maps to certificate with encrypt=true and trustservercertificate=false (go-mssqldb always verifies the hostname when encryption is on). The certificate file must have a .pem or .der extension. An explicit encrypt=strict is kept. Client certificates (cert/key) are not supported by the driver.

Amazon DynamoDB:

# .tbls.yml
dsn: dynamodb://us-west-2
# .tbls.yml
dsn: dynamo://ap-northeast-1?aws_access_key_id=XXXXXxxxxxxxXXXXXXX&aws_secret_access_key=XXXXXxxxxxxxXXXXXXX

To set AWS credentials, you can use

  1. Use default credential provider chain of AWS SDK for Go
  2. Add query to DSN
    • ?aws_access_key_id=XXXXXxxxxxxxXXXXXXX&aws_secret_access_key=XXXXXxxxxxxxXXXXXXX

Snowflake (Experimental):

---
# .tbls.yml
dsn: snowflake://user:password@myaccount/mydb/myschema

See also: https://pkg.go.dev/github.com/snowflakedb/gosnowflake

MongoDB:

# .tbls.yml
dsn: mongodb://mongoadmin:secret@localhost:27017/test
# .tbls.yml
dsn: mongodb://mongoadmin:secret@localhost:27017/test?sampleSize=20

If a field has multiple types, the multipleFieldType query can be used to list all the types.

# .tbls.yml
dsn: mongodb://mongoadmin:secret@localhost:27017/test?sampleSize=20&multipleFieldType=true

ClickHouse:

# .tbls.yml
dsn: clickhouse://dbuser:dbpass@hostname:9000/dbname

See also: https://pkg.go.dev/github.com/ClickHouse/clickhouse-go

Databricks (Experimental):

Personal Access Token (PAT) Authentication:

# .tbls.yml
dsn: databricks://your_databricks_workspace_id.cloud.databricks.com:443/sql/1.0/warehouses/your_warehouse_id?catalog=your_catalog&schema=your_schema&token=your_token

OAuth Client Credentials Authentication:

# .tbls.yml
dsn: databricks://your_databricks_workspace_id.cloud.databricks.com:443/sql/1.0/warehouses/your_warehouse_id?catalog=your_catalog&schema=your_schema&client_id=your_client_id&client_secret=your_client_secret

Required parameters:

  • your_databricks_workspace_id: databricks workspace ID
  • your_warehouse_id: databricks sql warehouse ID
  • your_catalog: Unity Catalog name

optional parameters:

  • your_schema: Schema/database name within the catalog. If not specified all tables in the catalogue will be documented and generated table references will include schema name.

Authentication (choose one):

  • PAT Authentication: token - Personal access token for authentication
  • OAuth Authentication: client_id and client_secret - OAuth M2M client credentials

See also: https://pkg.go.dev/github.com/databricks/databricks-sql-go

JSON:

The JSON file output by the tbls out -t json command can be read as a datasource (JSON Schema is here).

---
# .tbls.yml
dsn: json://path/to/testdb.json

HTTP:

---
# .tbls.yml
dsn: https://hostname/path/to/testdb.json
---
# .tbls.yml
dsn:
  url: https://hostname/path/to/testdb.json
  headers:
    Authorization: token GITHUB_OAUTH_TOKEN

GitHub:

---
# .tbls.yml
dsn: github://k1LoW/tbls/sample/mysql/schema.json

External database driver

tbls can integrate with external database drivers. If an executable with the pattern tbls-driver-* is on the PATH, tbls will recognize the corresponding scheme.

For example, if you have an executable named tbls-driver-foodb, tbls will recognize the foodb:// scheme.

tbls-driver-foodb receives the DSN at runtime via the environment variable TBLS_DSN. By outputting schema.json via STDOUT, tbls will work with it.

Document path

tbls doc generates document in the directory specified by docPath:.

# .tbls.yml
# Default is `dbdoc`
docPath: doc/schema

Document format

format: is used to change the document format.

# .tbls.yml
format:
  # Adjust the column width of Markdown format table
  # Default is false
  adjust: true
  # Sort the order of table list and columns
  # Default is false
  sort: false
  # Display sequential numbers in table rows
  # Default is false
  number: false
  # The comments for each table in the Tables section of the index page will display the text up to the first double newline (first paragraph).
  # Default is false
  showOnlyFirstParagraph: true
  # Hide table columns without values
  # Default is false
  hideColumnsWithoutValues: true
  # It can be boolean or array
  # hideColumnsWithoutValues: ["Parents", "Children"]

ER diagram

tbls doc generate ER diagram images at the same time.

# .tbls.yml
er:
  # Skip generation of ER diagram
  # Default is false
  skip: false
  # ER diagram image format (`png`, `jpg`, `svg`, `mermaid`)
  # Default is `svg`
  format: svg
  # Add table/column comment to ER diagram
  # Default is false
  comment: true
  # Hide relation definition from ER diagram
  # Default is false
  hideDef: true
  # Show column settings in ER diagram. If this section is not set, all columns will be displayed (default).
  showColumnTypes:
    # Show related columns
    related: true
    # Show primary key columns
    primary: true
  # Distance between tables that display relations in the ER
  # Default is 1
  distance: 2
  # ER diagram (png/jpg) font (font name, font file, font path or keyword)
  # Default is "" (system default)
  font: M+

It is also possible to personalize the output by providing your own templates. See the Personalized Templates section below.

Lint

tbls lint work as linter for database.

# .tbls.yml
lint:
  # require table comment
  requireTableComment:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: false
  # require column comment
  requireColumnComment:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: true
    # exclude columns from warnings
    exclude:
      - id
      - created_at
      - updated_at
    # exclude tables from warnings
    excludeTables:
      - logs
      - comment_stars
  # require index comment
  requireIndexComment:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: false
    # exclude indexes from warnings
    exclude:
      - user_id_idx
    # exclude tables from warnings
    excludeTables:
      - logs
      - comment_stars
  # require constraint comment
  requireConstraintComment:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: false
    # exclude constrains from warnings
    exclude:
      - unique_user_name
    # exclude tables from warnings
    excludeTables:
      - logs
      - comment_stars
  # require trigger comment
  requireTriggerComment:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: false
    # exclude triggers from warnings
    exclude:
      - update_count
    # exclude tables from warnings
    excludeTables:
      - logs
      - comment_stars
  # require table labels
  requireTableLabels:
    enabled: true
    # all commented, or all uncommented.
    allOrNothing: false
    # exclude tables from warnings
    exclude:
      - logs
  # find a table that has no relation
  unrelatedTable:
    enabled: true
    # all related, or all unrelated.
    allOrNothing: true
    # exclude tables from warnings
    exclude:
      - logs
  # check max column count
  columnCount:
    enabled: true
    max: 10
    # exclude tables from warnings
    exclude:
      - user_options
  # require columns
  requireColumns:
    enabled: true
    columns:
      -
        name: created
      -
        name: updated
        exclude:
          - logs
          - CamelizeTable
  # check duplicate relations
  duplicateRelations:
    enabled: true
  # check if the foreign key columns have an index
  requireForeignKeyIndex:
    enabled: true
    exclude:
      - comments.user_id
  # checks if labels are in BigQuery style (https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
  labelStyleBigQuery:
    enabled: true
    exclude:
      - schema_migrations
  # checks if tables are included in at least one viewpoint
  requireViewpoints: 
    enabled: true
    exclude:
      - schema_migrations

Filter tables

filter tables

include: and exclude: are used to filter target tables from tbls *.

# .tbls.yml
include:
  - some_prefix_*
exclude:
  - some_prefix_logs
  - CamelizeTable

lintExclude: is used to exclude tables from tbls lint.

# .tbls.yml
lintExclude:
  - CamelizeTable
Filter logic
  1. Add tables/functions from include
  2. Remove tables/functions from exclude
    • Check for include/exclude overlaps
    • If include is more specific than exclude (i.e. schema.MyTable > schema.* or schema.MyT* > schema.*), include the table(s)/function(s). If include is equally or less specific than exclude, exclude wins.
  3. Result

Comments

comments: is used to add table/column comment to database document without ALTER TABLE.

For example, you can add comment about VIEW TABLE or SQLite tables/columns.

Notice: Comments defined in .tbls.yml will override existing comments in the schema.

# .tbls.yml
comments:
  -
    table: users
    # table comment
    tableComment: Users table
    # column comments
    columnComments:
      email: Email address as login id. ex. user@example.com
    # labels for tables
    labels:
      - privary data
      - backup:true
  -
    table: post_comments
    tableComment: post and comments View table
    columnComments:
      id: comments.id
      title: posts.title
      post_user: posts.users.username
      comment_user: comments.users.username
      created: comments.created
      updated: comments.updated
  -
    table: posts
    # index comments
    indexComments:
      posts_user_id_idx: user.id index
    # constraints comments
    constraintComments:
      posts_id_pk: PRIMARY KEY
    # triggers comments
    triggerComments:
      update_posts_updated: Update updated when posts update

Relations

relations: is used to add or override table relation to database document without FOREIGN KEY.

You can create ER diagrams with relations without having foreign key constraints.

relations:
  -
    table: logs
    columns:
      - user_id
    parentTable: users
    parentColumns:
      - id
    # Relation definition
    # Default is `Additional Relation`
    def: logs->users
  -
    table: logs
    columns:
      - post_id
    parentTable: posts
    parentColumns:
      - id
  -
    table: logs
    columns:
      - comment_id
    parentTable: comments
    parentColumns:
      - id
  -
    table: logs
    columns:
      - comment_star_id
    parentTable: comment_stars
    parentColumns:
      - id

img

Override relations

If you want to override an existing relation, set the override: to true.

relations:
  -
    table: posts
    columns:
      - user_id
    cardinality: zero or one
    parentTable: users
    parentColumns:
      - id
    parentCardinality: one or more
    override: true
    def: posts->users
Automatically detect relations

detectVirtualRelations: if enabled, automatically detect relations from table and column names.

detectVirtualRelations:
  enabled: true
  strategy: default
Supported strategies
strategy name relation from relation to
default some_table.user_id users.id
singularTableName some_table.user_id user.id
identical some_table.user_id users.user_id
identicalSingularTableName some_table.user_id user.user_id
invertedSingularTableName some_table.id_user user.id

Dictionary

dict: is used to replace title/table header of database document

# .tbls.yml
---
dict:
  Tables: テーブル一覧
  Description: 概要
  Columns: カラム一覧
  Indexes: INDEX一覧
  Constraints: 制約一覧
  Triggers: トリガー
  Relations: ER図
  Name: 名前
  Comment: コメント
  Type: タイプ
  Default: デフォルト値
  Children: 子テーブル
  Parents: 親テーブル
  Definition: 定義
  Table Definition: テーブル定義

Personalized Templates

It is possible to provide your own templates to personalize the documentation generated by tbls by adding a templates: section to your configuration. For example:

templates:
  dot:
    schema: 'templates/schema.dot.tmpl'
    table: 'templates/table.dot.tmpl'
  puml:
    schema: 'templates/schema.puml.tmpl'
    table: 'templates/table.puml.tmpl'
  md:
    index: 'templates/index.md.tmpl'
    table: 'templates/table.md.tmpl'

A good starting point to design your own template is to modify a copy the default ones for Dot, PlantUML and markdown.

Required Version

The requiredVersion setting defines a version constraint string. This defines which version of tbls can be used in the configuration.

requiredVersion: '>= 1.42, < 2'

Expand environment variables

All configuration values can be set by expanding the environment variables.

# .tbls.yml
dsn: my://${MYSQL_USER}:${MYSQL_PASSWORD}@hostname:3306/${MYSQL_DATABASE}

Viewpoints

Viewpoints of your database schema based on concerns of your domain and add description to them. You can also define groups of tables within viewpoints.

# .tbls.yml

viewpoints:
  -
    id: comments-on-post
    name: comments on post
    desc: Users can comment on each post multiple times and put a star on each comment.
    tables:
      - users
      - posts
      - comments
      - comment_stars
      - post_comments
      - post_comment_stars
    groups:
      -
        name: Comments
        desc: Tables about comments
        tables:
          - posts
          - comments
          - post_comments
      -
        name: Stars
        desc: Tables about stars
        tables:
          - comment_stars
          - post_comment_stars

id is optional. When set, it is used as the suffix of the viewpoint output file name (e.g. viewpoint-comments-on-post.md) instead of the index, so the file name stays stable regardless of the viewpoint order. id must be unique and must not contain path separators (/ or \). It is also used to specify the viewpoint in tbls out --viewpoint.

Output formats

tbls out output in various formats.

Markdown:

$ tbls out -t md -o schema.md

DOT:

$ tbls out -t dot -o schema.dot

PlantUML:

$ tbls out -t plantuml -o schema.puml

Mermaid:

$ tbls out -t mermaid -o schema.mmd

Image (svg, png, jpg):

$ tbls out -t svg --table users --distance 2 -o users.svg

Viewpoint:

Output only the schema of a specific viewpoint by specifying its id (or index).

$ tbls out -t svg --viewpoint comments-on-post -o comments-on-post.svg

With -t md, the viewpoint document (including groups and the ER diagram inlined as Mermaid) is generated instead of a plain schema document.

$ tbls out -t md --viewpoint comments-on-post -o comments-on-post.md

JSON:

$ tbls out -t json -o schema.json

Tips: tbls doc can load schema.json as DSN.

$ tbls doc json:///path/to/schema.json

YAML:

$ tbls out -t yaml -o schema.yaml

Excel:

$ tbls out -t xlsx -o schema.xlsx

.tbls.yml:

$ tbls out -t config -o .tbls.new.yml

Command arguments

tbls subcommands (doc,diff, etc) accepts arguments and options

$ tbls doc my://root:mypass@localhost:3306/testdb doc/schema

You can check available arguments and options using tbls help [COMMAND].

$ tbls help doc
'tbls doc' analyzes a database and generate document in GitHub Friendly Markdown format.

Usage:
  tbls doc [DSN] [DOC_PATH] [flags]

Flags:
  -j, --adjust-table       adjust column width of table
  -b, --base-url string    base url for links
  -c, --config string      config file path
  -t, --er-format string   ER diagrams output format (png, svg, jpg, mermaid). default: svg
  -f, --force              force
  -h, --help               help for doc
      --rm-dist            remove files in docPath before generating documents
      --sort               sort
      --when string        command execute condition
      --without-er         no generate ER diagrams

Output Schema data

tbls doc also output schema data (schema.json) to same directory as the generated schema document.

To disable output of schema data, set disableOutputSchema: to true in .tbls.yml file.

Environment variables

tbls accepts environment variables TBLS_DSN and TBLS_DOC_PATH

$ env TBLS_DSN=my://root:mypass@localhost:3306/testdb TBLS_DOC_PATH=doc/schema tbls doc

Frequently asked questions

Is tbls free to use?

tbls is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does tbls do?

tbls is a CI-Friendly tool to document a database, written in Go.

What is tbls written in?

tbls is primarily written in Go. Its source is publicly available at https://github.com/k1LoW/tbls, and it has 4,373 GitHub stars.