29

I am trying to integrate my Flask project with Alembic
My application structure looks like

project/
       configuration/
                    __init__.py
                    dev.py
                    test.py
       core/
           # all source code
       db/
         migrations/
                    __init__.py
                    alembic.ini
                    env.py
                    versions/

When I try to run the following from my db directory, I see

 File "migration/env.py", line 55, in run_migrations_online
    from configuration import app, db
ImportError: No module named configuration

I tried the solution mentioned in Request a simple alembic working example for Auto Generating Migrations, but it does not work for me

My method in env.py run_migrations_online() with change is

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.

    """
    import os
    import sys

    sys.path.append(os.getcwd())
    from configuration import app, db

    alembic_config = config.get_section(config.config_ini_section)
    alembic_config['sqlalchemy.url'] = app.config['SQLALCHEMY_DATABASE_URI']
    target_metadata = db.metadata

    engine = engine_from_config(
        alembic_config,
        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()

How can I fix this?

Community
  • 1
  • 1
daydreamer
  • 87,243
  • 191
  • 450
  • 722

4 Answers4

48

I did export PYTHONPATH=<path_to_project> and ran the command again and it ran successfully

daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • For a better, more permanent solution, I second what @Palasaty suggested. Just update your `env.py` file to use the correct directory. – Jeff May Jun 09 '17 at 18:32
  • 1
    My preferred solution echos @zzzeek's suggestion to use revision_environment=True to get revisions to use the `env.py`: https://alembic.zzzcomputing.com/en/latest/tutorial.html?highlight=revision_environment#editing-the-ini-file – nlloyd Oct 19 '18 at 15:07
  • 3
    PYTHONPATH=. willl include the current directory and it will do the trick as well. – Massimo Fazzolari Feb 22 '19 at 11:35
  • If your setup is docker-compose you can set this variable like: `docker-compose run --rm -e PYTHONPATH=. alembic ` for 1 time commands. – Bartłomiej Skwira Nov 20 '19 at 14:51
20

You say you run something like alembic migrate --autogenerate -m 'migration description' from the directory project/db and get ImportError, right?

If so, the problem is obvious.

See: you try to import configuration module and it results in errors. Then you put sys.path.append(os.getcwd()) - in other words, you add current directory to the system path. But what is the current directory? It's project/db, and it doesn't have configuration module under it, so you continue getting ImportError.

Solution is to add to system path parent directory - project, which contains configuration module. Like so:

parent_dir = os.path.abspath(os.path.join(os.getcwd(), ".."))
sys.path.append(parent_dir)
Palasaty
  • 5,181
  • 1
  • 26
  • 22
2

We've run into the same problem, it boils down to env.py not being called by revision unless the --autogenerate flag is set. You can test this by putting a print statement at the top of your env.py file.

We're working around it by calling with --autogenerate then removing the generated code.

Christophe Biocca
  • 3,388
  • 1
  • 23
  • 24
  • 1
    note you don't need --autogenerate, please use revision_environment=True: http://alembic.zzzcomputing.com/en/latest/tutorial.html?highlight=revision_environment#editing-the-ini-file – zzzeek Aug 23 '18 at 13:57
  • Have you found another way of envoking the `env.py` file without using `--autogenerate` ? – Dan Sep 15 '18 at 02:30
  • 1
    @zzzeek I tried using `revision_environment=true` but I'm seeing same issue. – Ganesh Satpute Oct 18 '19 at 10:27
  • 1
    The t in your `true` needs to be a capital T. It is Python. – dbinott Nov 05 '20 at 18:42
  • @dbinott it isn't python code, zzzeek is refering to the alembic.ini file from the shared link. BTW, I still have to use PYTHONPATH=. , revision_environment=true doesn't fix it for me (also tried True capital T) – José Ripoll Mar 30 '21 at 03:58
0

For those who don't want to set PYTHONPATH manually before running alembic. You may run alembic as a module, for instance:

python -m alembic.config upgrade head
gmagno
  • 1,770
  • 1
  • 19
  • 40