49

app/init.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__ name __)
db = SQLAlchemy(app)  
from app import views, models

app/models.py:

from app import db  # I want to avoid this everywhere

I really don't like my submodules having a dependency on their parent. Also can the global package variables be avoided too? I want a more OO solution.

One alternative for app is to use Blueprints I think, but then I loose the route decorator. Also the same cannot be done for db with SQLAlchemy (or can it?).

ovg
  • 1,486
  • 1
  • 18
  • 30
  • refer [this link](https://charlesleifer.com/blog/structuring-flask-apps-a-how-to-for-those-coming-from-django/) for a great guide towards creating project structure for flask. – code_10 Nov 20 '22 at 13:21

2 Answers2

71

Take a look at this project: https://github.com/sloria/cookiecutter-flask
It's a great example for doing things the right way. Many of great Flask features are used: blueprints, application factories and more.

Here is how they register extensions, such as SQLAlchemy Database:

# app/extensions.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
...


# app/app.py
from app.extensions import db

def create_app(config_object=ProdConfig):
    app = Flask(__name__.split('.')[0])
    app.config.from_object(config_object)
    register_extensions(app)
    ...

def register_extensions(app):
    db.init_app(app)
    ...
frainfreeze
  • 567
  • 6
  • 20
leovp
  • 4,528
  • 1
  • 20
  • 24
  • 1
    Great, I think this is exactly what I was looking for. So basically defining these globals in another package gets rid of the need for a circular import? That really cleans up the mess. – ovg Mar 20 '17 at 18:33
  • 1
    Exactly. Every object has its place and it's all neatly working together. – leovp Mar 20 '17 at 18:35
  • 6
    It took me an embarrassingly long time to get Flask setup the way I wanted. This helped tremendously. Many thanks. – Braden Holt Jun 14 '18 at 03:05
  • Guess it's the best practice – Mario Rojas Sep 07 '20 at 20:25
30

Try use 3rd. We create exts.py file to instancing SQLAlchemy like this:

exts.py

from flask_sqlalchemy import SQLAlchemy
from flask_xxx import xxx

db = SQLAlchemy()
...

run.py

from flask import Flask

from .exts import db, ...


def register_extensions(app):
    db.init_app(app) 
    ... 


def create_app(config):
    app = Flask(__ name __)
    app.config.from_object(config)

    register_extensions(app)

    return app

app = create_app(config)

models.py

from .exts import db


class XXXModel(db.Model):
    pass    
Legolas Bloom
  • 1,725
  • 1
  • 19
  • 17