Search code examples
pythonherokuflaskmongoengine

Flask and Gunicorn on Heroku import error


I have a small Flask app which uses MongoEngine.

my project structure:

/myproject
  -application.py
  -config.py
  /my_app
    -models.py
    -views.py

my application.py:

#!/usr/bin/env python
from flask.ext.mongoengine import MongoEngine
from config import app
import os
app.debug = True

# get config settings
if __name__ == '__main__':
    app.config.from_object('config')
else:
    app.config.from_object('heroku_config')

# wrap app in mongengine
db = MongoEngine(app)

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)

my models.py:

from application import db
from flask import url_for

# declare model classes
...

I am deploying on heroku. If my Procfile reads:

 web: python application.py

It works fine. When I try to switch to Gunicorn:

 web: gunicorn application:app  

When I start gunicorn it complains by way of an import error:

ImportError: cannot import name db

Why is this an issue now? I'm guessing it's a path problem but I can't see why so.


Solution

  • I assume you're registering blueprints or something like that in application.py, which in turn imports the model, right?
    You didn't supply the view file or how you're using the view file and if my guess isn't correct my answer below won't be either.

    If my guess is correct it is probably because of a circular import. You could create a db.py file that contains these lines (move from application.py):

    from flask.ext.mongoengine import MongoEngine
    db = MongoEngine(app)
    

    and then import that file into your models (from db import db).
    That means the flow would look something like this: db -> model -> view -> app instead of app (db) -> model -> view -> app.

    Circular imports creates all kinds of annoying problems, try to avoid them whenever possible.