A migration library for SQLAlchemy
Project description
SQLAltery
A migration library for SQLAlchemy. A cleaner frontend to Alembic.
Guide
Set up management script
SQLAltery provides the "functional core".
To use it in your project, you'll need to provide your own "imperative shell", but this is easy.
Here's a starter managedb.py:
import sqlalchemy as sa
from sqlaltery import SQLAltery
def cmd_diff() -> None:
# Show pending changes to schema
salt = _get_sqlaltery()
print(salt.diff(model.Base.metadata))
def cmd_commit() -> None:
# Create a new migration file from pending changes (if any)
salt = _get_sqlaltery()
# TODO: print created file; `data: bool` flag
salt.generate(model.Base.metadata)
def cmd_sync(*, revision: Optional[int] = None) -> None:
# Migrate your DB to `revision`. If `None`, this means the latest.
# `revision == 0` is a special revision that means an empty DB.
salt = _get_sqlaltery()
engine = _get_engine()
with salt.connect_to(engine) as migrator:
migrator.migrate(revision, initial = 0)
def _get_sqlaltery() -> SQLAltery:
# choose where to store migration files
from pathlib import Path
migration_dir = Path(__file__).parent / 'migration'
return SQLAltery(migration_dir)
def _get_engine() -> sa.Engine:
# an engine pointing to the DB you want to migrate
return sa.create_engine(sa.URL.create(...))
def _get_metadata() -> sa.MetaData:
# return your model metadata
from my_app import my_model
return my_model.Base.metadata
if __name__ == '__main__':
import funcli
funcli.run({ 'diff': cmd_diff, 'commit': cmd_commit, 'sync': cmd_sync })
Terminology used here
You can name the operations anything, but this guide will use these terms:
commit: create a new migration (Django:py manage.py makemigrations)sync: apply migrations (Django:py manage.py migrate)sync --fake: fake migrations (Django:py manage.py migrate --fake); this updates only the migration metadata (tablesqlaltery_migration)
Reset migrations
Assuming your database(s) are synced to latest, delete your migration dir, create a new migration, and do a fake sync:
rm -rf migration
py managedb.py commit
py managedb.py sync --fake
Data migrations
Data migrations usually involve a three-step process: expand, project, contract.
- Expand the schema:
T_oldtoT_exp \superset T_new, whereT_expis such that the underlying database can automatically project the data onto it (e.g., adding only nullable columns) - Project the data: apply a function
T_exp -> T_newto the data - Contract the schema:
T_exptoT_new
py managedb.py commit --data
Now, modify the newly created migration to and write code data migration code. Once you're done, sync:
py managedb.py sync
Status
-
MetaDatadiffing (sqlaltery/compare.py) - apply ops to
MetaData(sqlaltery/ops.py:apply) - apply ops to
Connection(sqlaltery/ops.py:apply); all the heavy lifting is passed to Alembic's DDL - write migration to a file (
sqlaltery/command.py:_save_migration) - allow multiple migrations per file (
OPSorOPS_{\d+};OPSis treated asOPS_0; for multiple, they're expected to be sequential from 0) -
generate(data: bool)that creates a new migration with expand/project/contract phases - tests (95%)
- docs
- document basic usage and show example script
Why not use Alembic directly?
- Alembic diffs the head MD against current DB, not against latest migration
- Alembic has split upgrade/downgrade
- Alembic requires you to manually manage metadata in migrations (for doing queries)
- Alembic creates a bunch of files (alembic.ini, env.py). The default case should be simple: just create an
SQLAlteryand use it; customize by passing arguments.
Internal use
Set up:
uv sync --no-install-project
Run tests:
py -m pytest
How to publish:
py -m build --wheel --installer=uv
python -m twine upload dist/<file>
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlaltery-0.5.2-py3-none-any.whl.
File metadata
- Download URL: sqlaltery-0.5.2-py3-none-any.whl
- Upload date:
- Size: 13.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23484215a14a05d2c50b1dfa91433567ba54fe3d1b4839caafa31020b99e4173
|
|
| MD5 |
ee844881f5de2ff45a56a55239d72b84
|
|
| BLAKE2b-256 |
94a2e6485a1b4e87353ff358f1a918348cf3082d94e3ee18964520d3fbed0ea3
|