0
votes

I've a question related to Flask-migrate. I'm creating a set of web services with Flask. I've split each web service in his own package in a python application.

The application structure look like this:

MyApp WS1 models.py WS2 models.py CommonPackage models.py

How can I import all the modules and init the db? I've tried to import them all manually but is not working. I know that it works if I import the "app" from WS1 or Ws2 separately, but I would like to do this in a single operation, is this possible?

Here you can find the code for Flask-migrate:

#!virtualenv/bin/python

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from config import SQLALCHEMY_DATABASE_URI

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db = SQLAlchemy(app)

migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

from WS1.models import Class1, Class2, Class3    <--- This is not importing
from WS2.models import Class4, Class5, Class6    <--- This is not importing

if __name__=='__main__':
    manager.run()

This is the modules where I initialize SQLAlchemy session:

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

engine = create_engine(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()

All the models import this module and inherit from Base.

Thanks a lot,

Enrico

1
Have you tried importing the models earlier, e.g. before initializing Migrate?lyschoening
I've tried but is not working anyway :/Enrico Bottani
The model classes would have to inherit from db.Model to be imported. I am guessing they do not because you would likely have an import cycle. Move the db declaration somewhere where you can import it without a cycle and have all your model classes extend db.Model.lyschoening
That is the thing, I'm quite new to python / flask / sqlalchemy. I've created a working proto of a solution and now I'm starting to write the actual solution properly. For this reason I'm trying to separate classes/modules/packages properly. What I came up with is that I created a SQLAlchemyDatabase module like the one you can find on the edited version of my question and then my SQLAlchemy models inherit from SQLAlchemyDatabase Base. This, from what I read, should be the proper why, am I wrong? (thx for your time :) )Enrico Bottani

1 Answers

1
votes

When you are defining a custom declarative base you're not really using Flask-SQLAlchemy anymore—and Flask-Migrate reads the models from Flask-SQLAlchemy's internal declarative base. (That is why you have to initialize Migrate with both app and db).

Flask has an answer to the import cycle problem: Most Flask extensions have an .init_app() method to defer initializing the extension where necessary.

In the module where you currently create Base by hand, just do db = SQLAlchemy() and then in your models import db and use db.Models as your declarative base instead of Base. In your app.py, do the following:

from dbpackagename import db

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI

db.init_app(app)