Search code examples
flaskflask-sqlalchemycode-structure

Best practice: Where should re-usable queries be placed?


Short

I have re-usable SQLAlchemy queries in a Flask application, but I do not know where it's best to place them.

Longer

When reading basic tutorials, it becomes very clear how to create basic SQLAlchemy models, such as this one representing a blog post:

class Blog(db.Model):

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.Text())
    body = db.Column(db.Text())
    date = db.Column(db.Date())

and how to perform a query, such as getting the blog posts by their date:

Blog.query.order_by(Blog.date.desc()).all()

But the examples are frequently shown as Python console commands, rather than in the context of an application. In the Flask Mega-Tutorial, the author seems to be perfectly content with having simple queries as part of his views.

But if we're dealing with complicated and/or re-usable querying statements, placing them into the middle of several views gets ugly fast.

So where should I put them? In "normal" MVC implementations I'd place this into the model classes. Is that the right approach in Flask? Or do the queries belong closer to the views? Should I be creating a separate module? Or is there no best practice to follow here?


Solution

  • For posterity: I ended up placing most of the query logic in the model classes as class methods.

    The toy Blog class from the question would then end up like this:

    class Blog(db.Model):
    
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.Text())
        body = db.Column(db.Text())
        date = db.Column(db.Date())
    
        @classmethod
        def get_by_date(cls):
            return cls.query.order_by(cls.date.desc()).all()
    

    I have not yet encountered problems (worth mentioning) with this approach.