Skip to main content
Geni provides full support for MySQL databases with native schema dumping and migration management.

Connection URL Format

MySQL connections use the following URL format:
mysql://user:password@host:port/database

URL Components

  • user - MySQL username
  • password - User password (optional)
  • host - Database server hostname or IP address
  • port - Database port (default: 3306)
  • database - Database name
URLs with localhost are automatically normalized to 127.0.0.1 for compatibility (source: mysql.rs:55-58).

Setup

1

Set your database URL

export DATABASE_URL="mysql://root:password@localhost:3306/myapp"
2

Create the database

geni create
This executes: CREATE DATABASE IF NOT EXISTS myapp
3

Create your first migration

geni new create_users_table
4

Run migrations

geni up

Configuration Examples

DATABASE_URL="mysql://root@localhost:3306/development"
DATABASE_WAIT_TIMEOUT="30"
DATABASE_MIGRATIONS_FOLDER="./migrations"

Features

Transaction Support

MySQL migrations run in transactions by default. To disable transactions for a specific migration, add a comment at the top:
-- transaction:no
ALTER TABLE users ADD INDEX idx_email (email);

Schema Dumping

Geni automatically dumps your MySQL schema after each successful migration. The schema dump includes:
  • Tables - Table definitions with columns, data types, and defaults
  • Views - View definitions
  • Constraints - Primary keys, foreign keys, and unique constraints
  • Indexes - Index definitions
  • Comments - Table and column comments
The schema is generated using MySQL’s INFORMATION_SCHEMA (source: mysql.rs:208-434).
MySQL schema dumping works without external tools by querying the information schema directly.

Wait Timeout

Geni can wait for MySQL to be ready before running migrations:
DATABASE_WAIT_TIMEOUT="30" geni up
The driver will retry the connection every second until the timeout is reached (source: mysql.rs:33-53).

Parameterized Queries

MySQL uses ? placeholders for prepared statements. Geni handles this automatically:
INSERT INTO schema_migrations (id) VALUES (?)
DELETE FROM schema_migrations WHERE id = ?

Database Operations

Create Database

geni create
Executes: CREATE DATABASE IF NOT EXISTS {database_name}

Drop Database

geni drop
Executes: DROP DATABASE IF EXISTS {database_name}
Dropping a database is irreversible. All data will be permanently deleted.

Check Status

geni status
Shows pending migrations by querying the schema_migrations table.

Limitations

None. MySQL is fully supported with all Geni features.

Examples

Basic Migration

Create a table in 20240115120000_create_users.up.sql:
CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(255) NOT NULL UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);
Rollback in 20240115120000_create_users.down.sql:
DROP TABLE IF EXISTS users;

MySQL-Specific Features

Using MySQL features:
CREATE TABLE products (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  price DECIMAL(10, 2) NOT NULL,
  metadata JSON,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Full-text index
CREATE FULLTEXT INDEX idx_products_name ON products(name);

Troubleshooting

Connection Issues

If you see connection errors, verify:
  • MySQL is running and accessible
  • Hostname and port are correct (default: 3306)
  • User credentials are valid
  • Database exists (or use geni create)
  • User has appropriate permissions

Localhost Resolution

Geni automatically converts localhost to 127.0.0.1 in MySQL URLs. If you need to use a Unix socket instead, use the full path:
DATABASE_URL="mysql://root@localhost/app?socket=/var/run/mysqld/mysqld.sock"

Migration Table

Geni creates a schema_migrations table to track applied migrations:
CREATE TABLE IF NOT EXISTS schema_migrations (
  id VARCHAR(255) PRIMARY KEY
)
You can customize the table name:
DATABASE_MIGRATIONS_TABLE="custom_migrations" geni up

Differences from PostgreSQL

  • Uses ? for parameterized queries instead of $1, $2
  • Includes IF NOT EXISTS / IF EXISTS in database operations
  • Auto-increments use AUTO_INCREMENT instead of SERIAL
  • Schema dumping uses INFORMATION_SCHEMA instead of system catalogs

Build docs developers (and LLMs) love