My application has a blueprint which is intended to be modular and uses its own database models. I use an app-factory pattern.
Two problems that I face often with such a project structure are:
- Cyclical imports.
- The inability to pass around the
db
object to the blueprints in a clean manner such that they can create their own database models.
To avoid passing the db
object around I have now started to create a new database object (db = SQLAlchemy()
) within the blueprints itself.
It works! And also avoids some issues with cyclical imports as well since the blueprint now uses its own instance of db
. My questions is, what kind of problems will this design lead to? I use gunicorn
with a gevent
worker.
Here's some sample code to show how my models and factory are structured:
blueprints.status.models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Status(db.Model):
__tablename__ = 'states'
id = db.Column(db.Integer, primary_key=True)
job_id = db.Column(db.Integer)
status = db.Column(db.String(120))
models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Job(db.Model):
__tablename__ = 'states'
id = db.Column(db.Integer, primary_key=True)
state = db.Column(db.String(120)
factory.py
from .blueprints.status.models import db as status_db # blueprint db
from .blueprints.status.routes import status_handler # blueprint handler
from .models import db as root_db # root db
from flask import Flask
def create_app():
app = Flask(__name__)
# Create database resources.
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////path/to/app.db'
root_db.init_app(app)
status_db.init_app(app)
with app.app_context():
root_db.create_all()
status_db.create_all() # <--- What problems will this lead to?
# Register blueprint routes.
app.register_blueprint(status_handler, url_prefix="/status")
return app
Aucun commentaire:
Enregistrer un commentaire