Skip to content

Pelican

A modern, minimal migration framework for SQLAlchemy

Tests CodeQL Advanced PyPI - Version OpenSSF Scorecard

DocumentationSource Code


Pelican is a lightweight tool for managing database schema changes. It focuses on readability, simplicity and clean developer experience.

"""20251002014707 - Create spaceships"""
from pelican import migration, create_table, drop_table


@migration.up
def upgrade():
    with create_table('spaceships') as t:
        t.string('name', nullable=False)
        t.integer('crew_capacity', default=1)
        t.timestamps()


@migration.down
def downgrade():
    drop_table('spaceships')

Create and activate a virtual environment and install Pelican:

pip install pelican-migration

Pelican reads the database URL from a DATABASE_URL environment variable or a .env file in your project root:

DATABASE_URL=postgresql://user:password@localhost/mydb

Supported databases: SQLite, PostgreSQL.

Generate a migration

pelican generate create_spaceships

Creates db/migrations/<timestamp>_create_spaceships.py from the default template.

Apply migrations

pelican up          # apply all pending migrations
pelican up 123      # apply a specific revision

Roll back

pelican down        # roll back the latest applied migration
pelican down 123    # roll back a specific revision

Check status

pelican status
Migration Status
------------------------------
✓ 20251001120000 Create users
✓ 20251002014707 Create spaceships
○ 20251003090000 Add crew manifest

Schema DSL

create_table

from pelican import create_table

with create_table('spaceships') as t:
    t.string('name', nullable=False)
    t.integer('crew_capacity', default=1)
    t.boolean('active', default=True)
    t.text('description')
    t.references('user')        # adds user_id FK → users.id
    t.timestamps()              # adds created_at and updated_at
    t.index(['name'], unique=True)

change_table

from pelican import change_table

with change_table('spaceships') as t:
    t.string('designation')         # add column
    t.rename('name', 'full_name')   # rename column
    t.drop('description')           # drop column
    t.remove_index(['full_name'])    # drop index

drop_table

from pelican import drop_table

drop_table('spaceships')

Column types

Method SQLAlchemy type
t.integer(name) Integer
t.float(name) Float
t.double(name) Double
t.boolean(name) Boolean
t.string(name, length=255) String
t.text(name) Text
t.datetime(name) DateTime
t.timestamps() created_at + updated_at
t.references(model) Integer FK to <model_plural>.id

All methods accept standard SQLAlchemy column kwargs (nullable, default, index, etc.).

Contributing

  • Fork the repository.
  • Install the development dependencies:
    pip install -e ".[dev]"
    
  • Open a PR with your improvements.