Pythonic way to correctly separate Model from application using SQLAlchemy
Question: I'm having a hard time to make my application run. Flask-SQLAlchemy extension
creates an empty database whenever I try to separate module in packages. To
better explain what I'm doing, let me show how my project is structured:

    
    
    Project
    |
    |-- Model
    |   |-- __init__.py
    |   |-- User.py
    |
    |-- Server
    |   |-- __init__.py
    |
    |-- API
    |   |-- __init__.py
    

The idea is simple: I want to create a package for my model, as I don't like
spreading code in a single package, and separate "sub" projects (like API), as
in the future I will be using blueprints to better isolate sub apps.

The code is very simple:

First, the `Model.__init__.py`:

    
    
    from flask_sqlalchemy import SQLAlchemy
    db = SQLAlchemy()
    

Note that I created this only to use a single `SQLAlchemy()` object accross
the package. No we go to Model.User

    
    
    from Model import db
    
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        Name = db.Column(db.String(80))
        Age = db.Column(db.Integer)
        ...
    

Once again note the from Model import db that I used to allow the same db
object.

Finally, the `Server.__init__.py` goes like this:

    
    
    from flask import Flask
    from flask_sqlalchemy import SQLAlchemy
    import Model, API
    db = Model.db
    
    
    def main():
        app = Flask("__main__")
        db = SQLAlchemy(app)
        db.create_all()
        API.SetAPIHookers(app)
        app.run(host="0.0.0.0", port=5000, debug=True)
    
    if __name__ == "__main__":
        main()
    

From my point of view, the `db = SQLAlchemy(app)` allows me to pass my app
object without creating a circular reference.

The problem is that whenever I run this code, the sqlite database file is
created empty. That made me think that maybe Python don't import things like I
thought it would. So I tested my theory by removing the import Model and
creating the user directly inside Server... and voilá, it worked!

Now comes my question: Is there a 'pythonic' way to correctly separate modules
like I want or should I leave everything in the same package?


Answer: Right now, you have set up your application using what is a rough equivalent
to the "[Application
Factory](http://flask.pocoo.org/docs/patterns/appfactories/)" pattern (so
called by the Flask documentation). This is a Flask idea, not a Python one. It
has some advantages, but it also means that you need to do things such as
initialize your SQLAlchemy object using the `init_app` method rather than the
SQLAlchemy constructor. There is nothing "wrong" with doing it this way, but
it means that you need to run methods like `create_all()` within an
[application context](http://flask.pocoo.org/docs/appcontext/), which
currently you would not be if you tried to run it in the `main()` method.

There are a few ways you can resolve this, but it's up to you to determine
which one you want (there is no right answer):

## Don't use the Application Factory pattern

In this way, you don't create the app in a function. Instead, you put it
somewhere (like in `project/__init__.py`). Your `project/__init__.py` file can
import the `models` package, while the `models` package can import `app` from
`project`. This is a circular reference, but that's okay as long as the `app`
object is created in the `project` package first before `model` tries to
import `app` from `package`. See the Flask docs on [Larger Application
Patterns](http://flask.pocoo.org/docs/patterns/packages/) for an example where
you can split your package into multiple packages, yet still have these other
packages be able to use the `app` object by using circular references. The
docs even say:

> Every Python programmer hates them, and yet we just added some: circular
> imports. [...] Be advised that this is a bad idea in general but here it is
> actually fine.

If you do this, then you can change your `Models/__init__.py` file to build
the `SQLAlchemy` object with a reference to the app in the constructor. In
that way, you can use `create_all()` and `drop_all()` methods of the
`SQLAlchemy` object, [as described in the documentation for Flask-
SQLAlchemy](http://pythonhosted.org/Flask-SQLAlchemy/api.html#configuration).

## Keep how you have it now, but build in a request_context()

If you continue with what you have now (creating your app in a function), then
you will need to build the `SQLAlchemy` object in the `Models` package without
using the `app` object as part of the constructor (as you've done). In your
main method, change the...

    
    
    db = SQLAlchemy(app)
    

...to a...

    
    
    db.init_app(app)
    

Then, you would need to move the `create_all()` method into a function inside
of the application context. A common way to do this for something this early
in the project would be to utilize the
[`before_first_request()`](http://flask.pocoo.org/docs/api/#flask.Flask.before_first_request)
decorator....

    
    
    app = Flask(...)
    
    @app.before_first_request
    def initialize_database():
        db.create_all()
    

The "initialize_database" method is run before the first request is handled by
Flask. You could also do this at any point by using the `app_context()`
method:

    
    
    app = Flask(...)
    with app.app_context():
        # This should work because we are in an app context.
        db.create_all()
    

Realize that if you are going to continue using the Application Factory
pattern, you should really understand how the application context works; it
can be confusing at first but necessary to realize what errors like
"application not registered on db instance and no application bound to current
context" mean.

