Skip to main content

Overview

The geni up command applies all pending migrations to your database, bringing it to the latest version. It automatically tracks which migrations have been applied and only runs new ones.

Usage

DATABASE_URL="<connection-string>" geni up

Required Environment Variables

DATABASE_URL
string
required
The database connection string. Format varies by database type.Examples:
  • PostgreSQL: postgres://user:password@localhost:5432/dbname?sslmode=disable
  • MySQL: mysql://root:password@localhost:3306/app
  • MariaDB: mariadb://root:password@localhost:3307/app
  • SQLite: sqlite://./database.sqlite
  • LibSQL: https://localhost:6000

Optional Environment Variables

DATABASE_TOKEN
string
default:"none"
Authentication token for LibSQL/Turso databases. Only required when connecting to Turso or LibSQL instances that require authentication.
DATABASE_MIGRATIONS_FOLDER
string
default:"./migrations"
Path to the directory containing migration files.
DATABASE_MIGRATIONS_TABLE
string
default:"schema_migrations"
Name of the table used to track applied migrations.
DATABASE_SCHEMA_FILE
string
default:"schema.sql"
Filename for the dumped database schema.
DATABASE_WAIT_TIMEOUT
number
default:"30"
Number of seconds to wait for the database to be ready before timing out. Useful when the database needs time to boot.
DATABASE_NO_DUMP_SCHEMA
boolean
default:"false"
Set to true to disable automatic schema dumping after migrations.

How It Works

  1. Connect to the database using the provided URL
  2. Create the migrations tracking table if it doesn’t exist
  3. Scan the migrations folder for .up.sql files
  4. Compare with applied migrations in the database
  5. Execute pending migrations in timestamp order
  6. Record each successful migration in the tracking table
  7. Dump the database schema to a file (unless disabled)

Examples

PostgreSQL

DATABASE_URL="postgres://postgres:password@localhost:5432/app?sslmode=disable" geni up
```bash

**Output:**
```text
Running migration 1709395200
Running migration 1709395245
Running migration 1709395300
Success

MySQL

DATABASE_URL="mysql://root:password@localhost:3306/app" geni up

SQLite

DATABASE_URL="sqlite://./database.sqlite" geni up
For SQLite, Geni will automatically create the database file if it doesn’t exist.

LibSQL/Turso

DATABASE_URL="https://my-database-user.turso.io" \
DATABASE_TOKEN="eyJhbGc..." \
geni up

Custom Configuration

DATABASE_URL="postgres://localhost/mydb" \
DATABASE_MIGRATIONS_FOLDER="./db/migrations" \
DATABASE_MIGRATIONS_TABLE="my_migrations" \
DATABASE_SCHEMA_FILE="current_schema.sql" \
geni up

In CI/CD

# Environment variables set by CI/CD platform
geni up

Transaction Behavior

By default, each migration runs inside a database transaction. If a migration fails:
  • The transaction is rolled back
  • The migration is not recorded as applied
  • Geni exits with an error
  • No subsequent migrations are run

Disabling Transactions

Some operations cannot run in transactions. Add this comment to the top of your migration file:
-- transaction:no
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
Without transactions, partial migrations may leave your database in an inconsistent state if they fail. Use -- transaction:no only when necessary.

Schema Dumping

After successfully applying migrations, Geni automatically dumps your database schema to a file. This provides:
  • Version control: Track schema changes alongside code
  • Documentation: See the current database structure at a glance
  • Disaster recovery: Reconstruct schema from a known good state

Generated Schema File

By default, creates schema.sql in your migrations folder:
-- Schema dump generated by Geni
-- Database: PostgreSQL
-- Timestamp: 2024-03-02 10:30:00

CREATE TABLE schema_migrations (
    version VARCHAR(255) PRIMARY KEY
);

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);

Disable Schema Dumping

DATABASE_URL="postgres://localhost/app" \
DATABASE_NO_DUMP_SCHEMA="true" \
geni up

Migration Tracking Table

Geni creates a table (default: schema_migrations) to track applied migrations:
CREATE TABLE schema_migrations (
    version VARCHAR(255) PRIMARY KEY
);
Each row contains a migration timestamp:
version
--------------
1709395200
1709395245
1709395300
Each row contains a migration timestamp:
version
--------------
1709395200
1709395245
1709395300

Error Handling

No Migrations Found

Couldn't read migration folder: No such file or directory
Solution: Create the migrations folder or set DATABASE_MIGRATIONS_FOLDER correctly.

Connection Failed

No database url found, please set the DATABASE_URL environment variable
Solution: Set the DATABASE_URL environment variable.

Migration Failed

Running migration 1709395300
Error: syntax error at or near "TABEL"
Solution: Fix the SQL syntax in the failing migration file. The migration was not recorded, so you can edit the file and run geni up again.

Docker Usage

docker run --rm -it --network=host \
  -v "$(pwd)/migrations:/migrations" \
  -e DATABASE_URL="postgres://localhost/app" \
  ghcr.io/emilpriver/geni:latest up

CI/CD Integration

GitHub Actions

- uses: emilpriver/geni@main
  with:
    migrations_folder: "./migrations"
    wait_timeout: "30"
    migrations_table: "schema_migrations"
    database_url: ${{ secrets.DATABASE_URL }}
    database_token: ${{ secrets.DATABASE_TOKEN }}

GitLab CI

migrate:
  image: ghcr.io/emilpriver/geni:latest
  script:
    - geni up
  variables:
    DATABASE_URL: $DATABASE_URL
  only:
    - main

Best Practices

  • Test locally first: Run geni up locally before deploying
  • Use transactions: Keep the default transaction behavior unless necessary
  • Check status first: Run geni status to see what will be applied
  • Backup production: Always backup production databases before running migrations
  • Monitor execution: Watch for errors during migration application
  • Version control schema: Commit the generated schema.sql file

Next Steps

Rollback Migrations

Undo migrations with geni down

Check Status

View migration status with geni status

Dump Schema

Export schema with geni dump

Create Database

Initialize database with geni create

Build docs developers (and LLMs) love