Question

I'm trying to use flask-migrate to version my database locally and then reflect the changes in production (Heroku). So far I managed to successfully version the local database and upgrade it, so now I wanted to reflect this on Heroku. To do this I pushed the latest code state to Heroku together with the newly created migrations folder and updated requirements.txt. I saw the dependencies were successfully installed:

Successfully installed Flask-Migrate alembic Flask-Script Mako

Then, I tried:

$ heroku run python app/hello.py db upgrade

Unfortunately I got this in response:

Running `python app/hello.py db upgrade` attached to terminal... up, run.4322
Traceback (most recent call last):
  File "app/hello.py", line 37, in <module>
    manager.run()
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 405, in run
    result = self.handle(sys.argv[0], sys.argv[1:])
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/__init__.py", line 384, in handle
    return handle(app, *positional_args, **kwargs)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_script/commands.py", line 145, in handle
    return self.run(*args, **kwargs)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_migrate/__init__.py", line 97, in upgrade
    config = _get_config(directory)
  File "/app/.heroku/python/lib/python2.7/site-packages/flask_migrate/__init__.py", line 37, in _get_config
    config.set_main_option('script_location', directory)
  File "/app/.heroku/python/lib/python2.7/site-packages/alembic/config.py", line 142, in set_main_option
    self.file_config.set(self.config_ini_section, name, value)
  File "/app/.heroku/python/lib/python2.7/ConfigParser.py", line 753, in set
    ConfigParser.set(self, section, option, value)
  File "/app/.heroku/python/lib/python2.7/ConfigParser.py", line 396, in set
    raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'alembic'

I googled to find what this might be and it looks like the config file can't be opened, however I have no idea what can be done to fix that. How come this works locally but not on Heroku?

Was it helpful?

Solution

I was struggling with this for some time and even posted on the Heroku python forums, but no replies so far. To solve the issue I decided not to run the migration remotely on Heroku, but to run the migration on my development machine and pass the production database address instead. So I do this:

  1. Sync the development db with production (when using Heroku you can easily do this with heroku pg:pull, you have to drop your local db prior to calling this method though)
  2. Assuming your models are already updated, run the python app.py db migrate. Important: I started getting the original error on my local too, I figured out I have to be in the exact same directory where my app.py is, otherwise I get the error.
  3. Review your auto-generated migration scripts
  4. Upgrade your local db with python app.py db upgrade
  5. Change the settings for your app to use the production db instead of your local development db and then run python app.py db upgrade again

After some thinking it struck me that this might have been the way this tool was designed to work. Although it still would be nice to be able to run the migrations remotely from Heroku, I'll settle for my solution as it is quicker and does the job.

OTHER TIPS

I haven't tried this with Heroku, but ran into the same error and symptoms. The issue for me was that when running locally, my current working directory was set to the project root directory, and when running remotely, it was set to the user's home directory.

Try either cd'ing to the right starting directory first, or pass the --directory parameter to the flask-migrate command with the absolute path to your migrations folder.

To elaborate on lawicko's answer, when using Flask-Migrate and Heroku, a good way to conduct database migrations for a production database is to download the production database, generate the migration script locally, and run the migration script on Heroku. The alternative is to use a local development database to generate migrations and run the migration script on Heroku for the production database, but if the local and production migrations become out of sync, errors will arise when performing database upgrades.

Here are the steps to download the production database and generate migrations locally in more detail:

  1. Use the command heroku pg:pull DATABASE_URL new_db_name -a heroku_app_name which creates a new local Postgres database with the name new_db_name and the same database schema and content of your Postgres database on Heroku. A database with the same name must not already exist. You can use a tool like Postico to view and manage your local Postgres databases with a GUI.

  2. Configure your Flask app to use the new Postgres database. Assuming Flask-SQLAlchemy is being used, in Flask's configuration set SQLALCHEMY_DATABASE_URI = "postgresql://localhost/new_db_name".

  3. Now that Flask recognizes the new local Postgres database mirroring the production database, use Flask-Migrate's flask db init and flask db migrate commands to generate a migration script.

  4. Push the migrations folder generated by Flask-Migrate to Heroku.

  5. Use Flask-Migrate to upgrade the production database on Heroku with heroku run flask db upgrade -a heroku_app_name.

Had the same issue as you. I then tried to commit migrations/alembic.ini and then things started to work. Just make sure there's no sensitive information inside that file before committing it. Hope this solves your issue too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top