| name | use-sql-migrate-sqlite |
| description | SQLite migrations with sql-migrate and litemigrate. Use when setting up SQLite migrations, configuring foreign keys, or using modernc.org/sqlite driver. |
| depends | ["use-sqlmigrate"] |
CLI setup
sql-migrate -d ./sql/migrations/ init --sql-command sqlite
Environment
SQLITE_PATH='./app.db'
Go library
import (
"database/sql"
_ "modernc.org/sqlite"
"github.com/therootcompany/golib/database/sqlmigrate"
"github.com/therootcompany/golib/database/sqlmigrate/litemigrate"
)
db, err := sql.Open("sqlite", dbPath+"?_pragma=foreign_keys(1)")
conn, err := db.Conn(ctx)
defer func() { _ = conn.Close() }()
runner := litemigrate.New(conn)
applied, err := sqlmigrate.Latest(ctx, runner, scripts)
MUST: The caller imports the SQLite driver (modernc.org/sqlite recommended — pure Go, no CGo).
SQL dialect notes
datetime('now') instead of CURRENT_TIMESTAMP for default values in expressions
TEXT for timestamp columns (SQLite has no native datetime type)
INSERT OR IGNORE for idempotent seeds (not INSERT IGNORE)
- String concatenation:
id || CHAR(9) || name (used by sync query)
ALTER TABLE ... DROP COLUMN requires SQLite 3.35.0+ (2021-03-12)
- "no such table" error string used to detect missing
_migrations table
- Default path:
todos.db if no env var set
sqlc with SQLite
SQLite CHAR(n) columns map to interface{} in sqlc. Use column-level overrides:
sql:
- schema: "sql/migrations/"
queries: "sql/queries/"
engine: "sqlite"
gen:
go:
out: "internal/tododb"
overrides:
- column: "todos.id"
go_type: "string"
- column: "todos.status"
go_type: "string"