Skip to content

Commit

Permalink
Document library use and embedding
Browse files Browse the repository at this point in the history
  • Loading branch information
amacneil committed Feb 21, 2023
1 parent a352145 commit 9e1cff8
Showing 1 changed file with 125 additions and 21 deletions.
146 changes: 125 additions & 21 deletions README.md
@@ -1,13 +1,14 @@
# Dbmate

[![Version](https://img.shields.io/github/release/amacneil/dbmate.svg)](https://github.com/amacneil/dbmate/releases)
[![Release](https://img.shields.io/github/release/amacneil/dbmate.svg)](https://github.com/amacneil/dbmate/releases)
[![Go Report](https://goreportcard.com/badge/github.com/amacneil/dbmate)](https://goreportcard.com/report/github.com/amacneil/dbmate)
[![Reference](https://img.shields.io/badge/go.dev-reference-blue?logo=go&logoColor=white)](https://pkg.go.dev/github.com/amacneil/dbmate/pkg/dbmate)

Dbmate is a database migration tool, to keep your database schema in sync across multiple developers and your production servers.
Dbmate is a database migration tool that will keep your database schema in sync across multiple developers and your production servers.

It is a standalone command line tool, which can be used with Go, Node.js, Python, Ruby, PHP, or any other language or framework you are using to write database-backed applications. This is especially helpful if you are writing many services in different languages, and want to maintain some sanity with consistent development tools.
It is a standalone command line tool that can be used with Go, Node.js, Python, Ruby, PHP, or any other language or framework you are using to write database-backed applications. This is especially helpful if you are writing multiple services in different languages, and want to maintain some sanity with consistent development tools.

For a comparison between dbmate and other popular database schema migration tools, please see the [Alternatives](#alternatives) table.
For a comparison between dbmate and other popular database schema migration tools, please see [Alternatives](#alternatives).

## Table of Contents

Expand All @@ -27,8 +28,13 @@ For a comparison between dbmate and other popular database schema migration tool
- [Migration Options](#migration-options)
- [Waiting For The Database](#waiting-for-the-database)
- [Exporting Schema File](#exporting-schema-file)
- [Internals](#internals)
- [schema_migrations table](#schema_migrations-table)
- [Library](#library)
- [Use dbmate as a library](#use-dbmate-as-a-library)
- [Embedding migrations](#embedding-migrations)
- [Concepts](#concepts)
- [Migration files](#migration-files)
- [Schema file](#schema-file)
- [Schema migrations table](#schema-migrations-table)
- [Alternatives](#alternatives)
- [Contributing](#contributing)

Expand All @@ -48,7 +54,7 @@ For a comparison between dbmate and other popular database schema migration tool

**macOS**

Install using Homebrew:
Install using [Homebrew](https://brew.sh/):

```sh
$ brew install dbmate
Expand All @@ -65,7 +71,7 @@ $ sudo chmod +x /usr/local/bin/dbmate

**Windows**

Download using [scoop](https://scoop.sh)
Install using [Scoop](https://scoop.sh)

```pwsh
scoop install dbmate
Expand Down Expand Up @@ -126,14 +132,14 @@ dbmate wait # wait for the database server to become available

The following options are available with all commands. You must use command line arguments in the order `dbmate [global options] command [command options]`. Most options can also be configured via environment variables (and loaded from your `.env` file, which is helpful to share configuration between team members).

- `--url, -u "protocol://host:port/dbname"` - specify the database url directly. _(env: `$DATABASE_URL`)_
- `--url, -u "protocol://host:port/dbname"` - specify the database url directly. _(env: `DATABASE_URL`)_
- `--env, -e "DATABASE_URL"` - specify an environment variable to read the database connection URL from.
- `--migrations-dir, -d "./db/migrations"` - where to keep the migration files. _(env: `$DBMATE_MIGRATIONS_DIR`)_
- `--migrations-table "schema_migrations"` - database table to record migrations in. _(env: `$DBMATE_MIGRATIONS_TABLE`)_
- `--schema-file, -s "./db/schema.sql"` - a path to keep the schema.sql file. _(env: `$DBMATE_SCHEMA_FILE`)_
- `--no-dump-schema` - don't auto-update the schema.sql file on migrate/rollback _(env: `$DBMATE_NO_DUMP_SCHEMA`)_
- `--wait` - wait for the db to become available before executing the subsequent command _(env: `$DBMATE_WAIT`)_
- `--wait-timeout 60s` - timeout for --wait flag _(env: `$DBMATE_WAIT_TIMEOUT`)_
- `--migrations-dir, -d "./db/migrations"` - where to keep the migration files. _(env: `DBMATE_MIGRATIONS_DIR`)_
- `--migrations-table "schema_migrations"` - database table to record migrations in. _(env: `DBMATE_MIGRATIONS_TABLE`)_
- `--schema-file, -s "./db/schema.sql"` - a path to keep the schema.sql file. _(env: `DBMATE_SCHEMA_FILE`)_
- `--no-dump-schema` - don't auto-update the schema.sql file on migrate/rollback _(env: `DBMATE_NO_DUMP_SCHEMA`)_
- `--wait` - wait for the db to become available before executing the subsequent command _(env: `DBMATE_WAIT`)_
- `--wait-timeout 60s` - timeout for --wait flag _(env: `DBMATE_WAIT_TIMEOUT`)_

## Usage

Expand Down Expand Up @@ -386,21 +392,119 @@ On Ubuntu or Debian systems, you can fix this by installing `postgresql-client`,

> Note: The `schema.sql` file will contain a complete schema for your database, even if some tables or columns were created outside of dbmate migrations.
## Internals
## Library

### schema_migrations table
### Use dbmate as a library

By default, dbmate stores a record of each applied migration in a `schema_migrations` table. This table will be created for you automatically if it does not already exist. The table schema is very simple:
Dbmate is designed to be used as a CLI with any language or framework, but it can also be used as a library in a Go application.

Here is a simple example. Remember to import the driver you need!

```go
package main

import (
"net/url"

"github.com/amacneil/dbmate/pkg/dbmate"
_ "github.com/amacneil/dbmate/pkg/driver/sqlite"
)

func main() {
u, _ := url.Parse("sqlite:foo.sqlite3")
db := dbmate.New(u)

err := db.CreateAndMigrate()
if err != nil {
panic(err)
}
}
```

See the [reference documentation](https://pkg.go.dev/github.com/amacneil/dbmate/pkg/dbmate) for more options.

### Embedding migrations

Migrations can be embedded into your application binary using Go's [embed](https://pkg.go.dev/embed) functionality.

Use `db.FS` to specify the filesystem used for reading migrations:

```go
package main

import (
"embed"
"fmt"
"net/url"

"github.com/amacneil/dbmate/pkg/dbmate"
_ "github.com/amacneil/dbmate/pkg/driver/sqlite"
)

//go:embed db/migrations/*.sql
var fs embed.FS

func main() {
u, _ := url.Parse("sqlite:foo.sqlite3")
db := dbmate.New(u)
db.FS = fs

fmt.Println("Migrations:")
migrations, err := db.FindMigrations()
if err != nil {
panic(err)
}
for _, m := range migrations {
fmt.Println(m.Version, m.FilePath)
}

fmt.Println("\nApplying...")
err = db.CreateAndMigrate()
if err != nil {
panic(err)
}
}
```

## Concepts

### Migration files

Migration files are very simple, and are stored in `./db/migrations` by default. You can create a new migration file named `[date]_create_users.sql` by running `dbmate new create_users`.
Here is an example:

```sql
-- migrate:up
create table users (
id integer,
name varchar(255),
);

-- migrate:down
drop table if exists users;
```

Both up and down migrations are stored in the same file, for ease of editing. When you apply a migration dbmate only stores the version number, not the contents, so you should always rollback a migration before modifying its contents. For this reason, you can safely rename a migration file without affecting its applied status, as long as you keep the version number intact.

### Schema file

The schema file is written to `./db/schema.sql` by default. It is a complete dump of your database schema, including any applied migrations, and any other modifications you have made.

This file should be checked in to source control, so that you can easily compare the diff of a migration. You can use the schema file to quickly restore your database without needing to run all migrations.

### Schema migrations table

Dbmate stores a record of each applied migration in table named `schema_migrations`. This table will be created for you automatically if it does not already exist.

The table is very simple:

```sql
CREATE TABLE IF NOT EXISTS schema_migrations (
version VARCHAR(255) PRIMARY KEY
)
```

Dbmate records only the version number of applied migrations, so you can safely rename a migration file without affecting its applied status.

You can customize the name of this table using the `--migrations-table` flag or `$DBMATE_MIGRATIONS_TABLE` environment variable. If you already have a table with this name (possibly from a previous migration tool), you should either manually update it to conform to this schema, or configure dbmate to use a different table name.
You can customize the name of this table using the `--migrations-table` flag or `DBMATE_MIGRATIONS_TABLE` environment variable.

## Alternatives

Expand Down

0 comments on commit 9e1cff8

Please sign in to comment.