Skip to content

dotlabshq/schemactl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

schemactl

framework‑agnostic database schema evolution tool for Python

schemactl is a next‑generation database migration tool built on top of SQLAlchemy metadata and Alembic autogeneration.

Unlike traditional migration tools, schemactl is designed as a schema evolution engine, not just a migration runner. It is architecture‑first, deterministic, and ready to integrate with LLMs, agents, and autonomous workflows.


Why schemactl?

Most migration tools are:

  • framework‑coupled
  • imperative and manual
  • hard to reason about at scale
  • unfriendly to AI‑assisted workflows

schemactl takes a different approach:

  • Framework‑agnostic – works with pure SQLAlchemy
  • Metadata‑driven – schema is the single source of truth
  • Diff‑based – migrations are generated from real schema changes
  • Deterministic – reproducible and auditable
  • AI‑ready – designed for LLM review, risk analysis, and human‑in‑the‑loop control

Core Concepts

Schema as Code

Your SQLAlchemy models (metadata) define the desired state of the database. For example, in app/models.py:

from sqlalchemy import Column, Integer, String, DateTime, Boolean
from sqlalchemy.orm import declarative_base
from datetime import datetime

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    email = Column(String(255), unique=True, nullable=False)
    username = Column(String(100), unique=True, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
    is_active = Column(Boolean, default=True)

schemactl compares this metadata against the actual database schema and generates migrations automatically.


Evolution, Not Just Migration

Instead of thinking in terms of "apply SQL files", schemactl models:

  • schema diffs
  • schema versions
  • schema state

This enables future features like:

  • automated rollback planning
  • migration safety scoring
  • AI‑assisted reviews
  • policy enforcement

Installation

pip install schemactl

CLI Overview

schemactl --help

Planned commands:

schemactl new       # generate a new migration from metadata diff
schemactl up        # create DB (if needed) and apply pending migrations
schemactl create    # create the database
schemactl drop      # drop the database
schemactl migrate   # run pending migrations
schemactl rollback  # rollback the last migration
schemactl down      # alias for rollback
schemactl status    # show migration status
#schemactl dump      # dump schema.sql
#schemactl load      # load schema.sql
schemactl wait      # wait for DB readiness

Usage

1. Generate a Migration

To generate an empty migration file:

schemactl new --message add_users_table

To auto-generate a migration based on model changes, use the --auto flag and specify the path to your models:

schemactl new \
  --message create_initial_tables \
  --auto \
  --models app.models

The command generates a new migration file:

migrations/
└── 20251215_create_initial_tables.sql

The content of the generated file will look like this:

-- migrate:up
-- Auto-generated migration: create_initial_tables
CREATE TABLE users (
    id SERIAL NOT NULL,
    email VARCHAR(255) NOT NULL,
    username VARCHAR(100) NOT NULL,
    created_at TIMESTAMP WITHOUT TIME ZONE,
    is_active BOOLEAN,
    PRIMARY KEY (id),
    UNIQUE (email),
    UNIQUE (username)
);

-- migrate:down
-- Rollback: create_initial_tables
DROP TABLE users;

2. Apply Migrations

schemactl up

What happens:

  • Creates the database if it does not exist
  • Ensures the schema_migrations table exists
  • Applies all pending migrations in order
  • Records applied revisions deterministically

Project Structure

.
├── schemactl/              # Main package source
│   ├── cli.py              # CLI commands
│   ├── services/           # Business logic and services
│   │   └── migration.py
│   │   └── model_loader.py
│   ├── adapters/           # Database and Alembic adapters
│   │   ├── alembic.py
│   │   └── database.py
├── migrations/             # Generated migration files
├── tests/                  # Unit and integration tests
├── pyproject.toml          # Project configuration (Poetry)
└── poetry.lock             # Poetry lock file

This structure follows Clean Architecture and keeps infrastructure concerns isolated.


Design Principles

  • Architecture first, code second
  • Prefer declarative over imperative
  • Explicit state tracking
  • Simple core, extensible edges

Status

⚠️ Early development / experimental

APIs may change. Migration format is not yet stable.


License

MIT


Contributing

Contributions are welcome, especially in:

  • migration safety
  • rollback logic
  • Async / cloud databases

Design discussions > code dumps.