2

I'm trying to build a webapp with flask, Mysql, SQLAlchemy and Alembic. But I'm not able to understand how imports work in python and how to set up my target_metadata to be able to use revision --autogenerate

Here is my directory's tree:

enter image description here

My website's init look like this:

import os
from flask import Flask

app = Flask(__name__, static_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)), '../static'))
app.config.from_pyfile('config.py', silent=True)

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))

Base = declarative_base()
Base.query = db_session.query_property()

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

from website import views

Then in my env.py when I try to import my Base like this:

from website import Base
target_metadata = Base.metadata

and try to run alembic revision --autogenerate ... I get this error: ImportError: No module named website.

And When I try to import Baselike this:

from website import Base
target_metadata = Base.metadata

I get this error: ValueError: Attempted relative import in non-package.

Please can you help me to understand how import works in python and how can I set my target_metadata ?

Bastien
  • 158
  • 1
  • 11

1 Answers1

3

I've just recently had this problem myself, though not with flask. What worked for me is simple, but it seems to be necessary (the current directory isn't on the pythonpath, so when you do from website import Base, python is throwing an exception because it can't find the website module).

Try adding this at the top of your env.py module:

import os
import sys
sys.path.append(os.getcwd())

It's a really hacky way to do it, but it works for me.

Also, just curious here... Is there any reason you aren't using libraries that do just about all of this for you? Think ones like flask-sqlalchemy, flask-migrate or flask-alembic (I forget which, but it wraps alembic for you). If your unaware of these, you might want to check out the flask extension registry. Some really handy ones there.

oliver2213
  • 141
  • 4