Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integrating Alembic with SQLAlchemy

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

The 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 sqlalchemy.url

I have the following in my env.py

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"

It says

Generating
migrations/versions/2d9d8de1aa80_initial.py...done

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!

like image 375
Sandeep Raju Prabhakar Avatar asked Feb 23 '13 06:02

Sandeep Raju Prabhakar


People also ask

What is SQLAlchemy Alembic?

Alembic is the migration tool we use with SQLAlchemy. Alembic provides us with a simple way to create and drop tables, and add, remove, and alter columns. Fork and clone this repository and we'll walk through writing Alembic migrations together. To install Alembic, run pip install alembic in your terminal.

How do you run all Alembic migrations?

Alembic is keeping track of the migrations in the alembic_version table on your database. Simple drop the table to start from scratch using the following command: DROP TABLE alembic_version; And then try to run your migration again!

Should I use Alembic?

Alembic is a very useful library widely used for database migration. It can be used to create tables, insert data or even migrate functions from one schema to another. To be able to do all these tasks, the library uses SQLAlchemy, an ORM that is suited for working with PostgreSQL and other relational databases.

What is Alembic DB?

Alembic is a lightweight database migration tool for usage with the SQLAlchemy Database Toolkit for Python.


1 Answers

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.

like image 79
JosefAssad Avatar answered Oct 21 '22 21:10

JosefAssad