I’m looking at a way to integrate Alembic with SQLAlchemy. What I need is a way so that Alembic detects any changes I make in
models.py automatically and updates it in the MySQL database when I run
alembic revision -m "<message_here>" and
alembic upgrade head.
Here is what I have at the moment.
This is my application directory structure.
/myapplication models.py __init__.py app.py /migrations env.py script.py.mako /versions
models.py contains the following.
from sqlalchemy import Column, Integer, String from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): """ `User` stores the basic info about a user """ __tablename__ = 'user' id = Column(Integer, primary_key=True) name = Column(String(255), nullable=False) phone = Column(String(15), nullable=False)
I have configured my
alembic.ini with my database credentials at
I have the following in my
from __future__ import with_statement from alembic import context from sqlalchemy import engine_from_config, pool from logging.config import fileConfig from myapplication import models # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config # Interpret the config file for Python logging. # This line sets up loggers basically. fileConfig(config.config_file_name) # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel # target_metadata = mymodel.Base.metadata target_metadata = models.Base.metadata # other values from the config, defined by the needs of env.py, # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. def run_migrations_offline(): """Run migrations in 'offline' mode. This configures the context with just a URL and not an Engine, though an Engine is acceptable here as well. By skipping the Engine creation we don't even need a DBAPI to be available. Calls to context.execute() here emit the given string to the script output. """ url = config.get_main_option("sqlalchemy.url") context.configure(url=url) with context.begin_transaction(): context.run_migrations() def run_migrations_online(): """Run migrations in 'online' mode. In this scenario we need to create an Engine and associate a connection with the context. """ engine = engine_from_config( config.get_section(config.config_ini_section), prefix='sqlalchemy.', poolclass=pool.NullPool) connection = engine.connect() context.configure( connection=connection, target_metadata=target_metadata ) try: with context.begin_transaction(): context.run_migrations() finally: connection.close() if context.is_offline_mode(): run_migrations_offline() else: run_migrations_online()
But when the run the migration using
alembic revision -m "initial"
But when I open the
migrations/versions/9aa5864e4c8_initial.py, this is what I see.
"""initial Revision ID: 2d9d8de1aa80 Revises: None Create Date: 2013-02-23 12:21:52.389906 """ # revision identifiers, used by Alembic. revision = '2d9d8de1aa80' down_revision = None from alembic import op import sqlalchemy as sa def upgrade(): pass def downgrade(): pass
The version file has nothing about the tables I was expecting it to create and later sync with MySQL when I run the command
alembic upgrade head. How do I configure Alembic so that when I run the
alembic revision command, It picks the schema from
models.py and generates a version file? I think I am missing something trivial here. Not sure what it is!
You want to run the revision subcommand with the –autogenerate flag so it inspects the models for changes.
alembic revision --autogenerate -m "some message"
Make sure you’re aware of the limitations of the autogenerate option.