Retort is a schema migration tool for SQLAlchemy, compares DB schema against table metadata, and updates DB schema according to this.
It depends on the Alembic autogenerate.
Retort works with
- Python 3.3+
- SQLAlchemy
- Alembic
- autopep8
$ pip install retort
$ python setup.py install
Generate config file (retort_config.py)
(venv) tpdn@example:~/retort_example$ retort init
Create retort_conf.py.
Edit config file
# retort_config.py
from model import user
TARGETS = [
{
'engine': user.engine, #sqlalchemy engine
'metadata': user.Base.metadata #sqlalchemy metadata
},
]
# model/user.py
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://foobar:abcdef@localhost/retort_test_db')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
fullname = Column(String(255))
xyz = Column(String(255))
Apply
(venv) tpdn@example:~/retort_example$ retort apply
====================
url: mysql+pymysql://foobar:abcdef@localhost/retort_test_db
logging_name: None
====================
op.create_table('users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('fullname', sa.String(length=255), nullable=True),
sa.Column('xyz', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('id')
)
Do you really want to apply this? [y/n]: y
Applying migration......
====================
url: mysql+pymysql://foobar:abcdef@localhost/retort_test_db
logging_name: None
====================
op.create_table('users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=255), nullable=True),
sa.Column('fullname', sa.String(length=255), nullable=True),
sa.Column('xyz', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('id')
)
---> Processing time: 0.0894(sec)
Complete!
Update model(remove xyz column)
# model/user.py
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://foobar:abcdef@localhost/retort_test_db')
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(255))
fullname = Column(String(255))
# xyz = Column(String(255))
Apply with --sql option
(venv) tpdn@example:~/retort_example$ retort apply --sql
====================
url: mysql+pymysql://foobar:abcdef@localhost/retort_test_db
logging_name: None
====================
ALTER TABLE users DROP COLUMN xyz;
Do you really want to apply this? [y/n]: y
Applying migration......
====================
url: mysql+pymysql://foobar:abcdef@localhost/retort_test_db
logging_name: None
====================
ALTER TABLE users DROP COLUMN xyz;
---> Processing time: 0.0745(sec)
Complete!
retort init retort apply --sql # print sql mode --dry-run # dry run (no database update) --yes # skip confirmation --without-drop # without drop operations (DROP TABLE, DROP COLUMN, DROP INDEX, DROP CONSTRAINT) retort print_operations --sql --without-drop
NAKAMORI Ryosuke - https://github.com/tpdn
BSD License (2-Clause)