onemig
v0.3.6
Published
CLI application for migrating MariaDB databases.
Maintainers
Readme
OneMig
The last migration tool you will ever need! 😂
OneMig is a CLI application for describing MariaDB table schemas in YAML, pulling schema resources from a live database, and generating migration SQL from those resources.
It is designed around a review-first workflow: generate SQL, inspect it, and then either apply it manually or rerun the command with --apply.
Installation
bun add onemigYou can also run the CLI through bunx:
bunx onemig --helpAgent Skill
OneMig includes an Agent Skill for Codex and other skill-aware agents. The skill teaches the agent when to use the onemig CLI, how to pull schema resources, how to generate pre/post migration SQL, and when --apply is safe to use.
From a project that has onemig installed or linked, install the skill from node_modules:
npx skills add ./node_modules/onemig/skills/onemig -a codexOr you can install it from GitHub:
npx skills add https://github.com/mnpenner/npm-packages/tree/main/packages/onemig/skills/onemig -a codexAdd -g to install the skill globally instead of only for the current project. Choose a symlink when prompted if you want local edits to the skill to be picked up during development.
Commands
onemig [global options] pull [-w | --dir=dir | --file=file]
onemig [global options] migrate [input] (--stage=pre|post | --pre | --post) [-w | --file=file] [--apply]
onemig [global options] kysley [--camel-case] [--file=file] [mysql2 type options]
onemig --help
onemig --versionpull, migrate, and kysley are implemented.
Connection Options
Commands that talk to the database accept global connection options before the command name:
onemig -h localhost -u root -D my_app -p pull-h, --host=name Connect to host.
-u, --user=name User for login.
-P, --port=# Port number to use for connection.
-D, --database=name Database to use.
-p, --password Prompt for password.Global options override environment variables. OneMig resolves connection settings in this order:
ONEMIG_URLorONEMIG_DATABASE_URLONEMIG_DB_HOST,ONEMIG_DB_PORT,ONEMIG_DB_USER,ONEMIG_DB_PASSWORD,ONEMIG_DB_PASSWORD_FILE,ONEMIG_DB_NAME,ONEMIG_DB_SOCKETDATABASE_URLDB_URLDB_HOST,DB_PORT,DB_USER,DB_USERNAME,DB_PASSWORD,DB_DATABASE,DB_NAME,DB_SOCKETMYSQL_HOST,MYSQL_TCP_PORT,MYSQL_PWD,MYSQL_UNIX_PORT
ONEMIG_DATABASE_URL=mariadb://user:password@localhost:3306/my_app
# or
ONEMIG_DB_HOST=localhost
ONEMIG_DB_PORT=3306
ONEMIG_DB_USER=root
ONEMIG_DB_PASSWORD=secret
ONEMIG_DB_NAME=my_appOneMig reads environment variables that are already present in the process; it does not load .env files itself. Bun users who want Bun's automatic .env and .env.local loading can run the CLI with Bun:
bunx --bun onemig migrate --stage=preNode users can preload env files with a tool such as dotenv-cli:
npx dotenv-cli -e .env -e .env.local -o -- onemig migrate --stage=prePulling Schema
Use pull to introspect the selected database and emit OneMig table resources.
onemig pullBy default, pull writes a YAML document stream to stdout. Use -w to write table files under onemig/tables/:
onemig pull -wWrite options print each file path after it is written.
You can also choose an output directory or single output file:
onemig pull --dir=schema
onemig pull --file=schema.yaml--write, --dir, and --file are mutually exclusive.
Writing Schema
OneMig reads YAML files containing one or more resource documents. The migration generator currently consumes Table resources. The schema also defines Database, SeedData, and User resources for future command support.
For editor validation, point YAML language tooling at the package schema:
# yaml-language-server: $schema=./node_modules/onemig/schema.jsonEach table resource describes columns, indexes, foreign keys, check constraints, triggers, and table options:
kind: Table
name: users
options:
engine: InnoDB
collation: utf8mb4_unicode_ci
columns:
- name: id
type: int
unsigned: true
autoIncrement: true
- name: email
type: varchar
length: 255
- name: created_at
type: datetime
fracDigits: 6
default: CURRENT_TIMESTAMP(6)
- name: metadata
type: json
nullable: true
indexes:
- name: PRIMARY
type: PRIMARY
columns:
- id
- name: uix_users_email
type: UNIQUE
columns:
- email
foreignKeys: []
checks:
- name: users_metadata_json
expr: JSON_VALID(`metadata`)
triggers: []Use oldNames to model table or column renames:
kind: Table
name: accounts
oldNames:
- users
columns:
- name: display_name
oldNames:
- name
type: varchar
length: 180
indexes: []
foreignKeys: []
checks: []
triggers: []Generating Migrations
Use migrate to compare desired YAML resources with the selected live database.
onemig migrate --stage=pre
onemig migrate --stage=post
onemig migrate --pre
onemig migrate --postThe optional positional input can be a YAML file or a directory containing .yaml and .yml files. It defaults to onemig.
onemig migrate schema.yaml --stage=pre
onemig migrate schema/ --stage=post
onemig migrate schema.yaml --pre
onemig migrate schema/ --postWithout --file, --write, or --apply, generated SQL is written to stdout:
onemig migrate --stage=pre > pre.sqlUse --file to choose an output file:
onemig migrate --stage=pre --file=onemig/migrations/pre.sqlUse -w or --write to write to onemig/migrations/YYYY-MM-DD-HHMM.sql:
onemig migrate --stage=pre --writeWrite options print the migration file path after it is written.
Use --apply to execute the generated statements against the selected database. It can be combined with --file or --write to keep a copy of the SQL that was applied.
onemig migrate --stage=pre --write --applyMigration Stages
--stage=pre or --pre is intended to run before deploying application code. It generates additive or widening changes such as:
- creating missing tables
- adding missing columns
- adding missing indexes and foreign keys when no column rename is pending
- widening
char,varchar,binary, andvarbinarylengths - increasing temporal fractional precision
- increasing decimal capacity without reducing scale
- promoting integer, text, or blob types to larger compatible types
--stage=post or --post is intended to run after deploying application code. It also generates cleanup and replacement changes such as:
- renaming tables and columns matched by
oldNames - dropping changed or extra indexes, foreign keys, check constraints, and triggers
- modifying changed columns and table options
- recreating changed indexes, foreign keys, check constraints, and triggers
- dropping extra columns
--drop-missing-tables is only valid with --stage=post and drops live tables that are not represented by the input resources.
onemig migrate --stage=post --drop-missing-tablesGenerating Kysely Types
Use kysley to generate Kysely schema types from the selected live database.
onemig kysleyWithout --file, writes TypeScript to stdout. Use --file to write the generated TypeScript to a file:
onemig kysley --file=src/db/schema.tsOptions
--camel-case Generate camelCase table and column keys for Kysely's CamelCasePlugin.
--date-strings Match mysql2 dateStrings: true; DATE, DATETIME, and TIMESTAMP select as string.
--decimal-numbers Match mysql2 decimalNumbers: true; DECIMAL selects as number.
--support-big-numbers Match mysql2 supportBigNumbers: true; unsafe BIGINT values can select as string.
--big-number-strings Match mysql2 bigNumberStrings: true. Requires --support-big-numbers.
--file=file Write generated TypeScript to file.Development
From this repository, run package checks with:
bun run check onemigBuild the package with:
bun run --cwd packages/onemig build