stefanobaldo
stefanobaldo

Reputation: 2063

Default scope for queries using Python + Flask-SqlAlchemy

I am writing an application using Python + Flask-SqlAlchemy extension.

I have the following code:

class Resource(db.Model):
    __tablename__ = 'resources'
    id = db.Column(db.Integer, primary_key=True)
    created_at = db.Column(db.DateTime)
    updated_at = db.Column(db.DateTime)
    is_active = db.Column(db.Boolean)
    key = db.Column(db.String(64))
    title = db.Column(db.String(64))

    def __init__(self):
        self.created_at = datetime.now()
        self.updated_at = datetime.now()
        self.is_active = 1

@app.route('/resources', methods=['GET'])
def resources_get_all():
    get_limits()
    resources = []
    data = Resource.query.filter(Resource.is_active == 1).limit(LIMIT).offset(OFFSET).all()
    for row in data:
        resources.append(
            resources_show(row)
        )
    return envelope(resources)

Is there a way to make all queries to the database automatically implement .filter(ModelName.is_active == 1).limit(LIMIT).offset(OFFSET)? I do not want to keep passing this block to all queries in the whole application. I want to create something like a default scope to the queries.

Upvotes: 2

Views: 1300

Answers (1)

chfw
chfw

Reputation: 4592

One of many ways is to add class method. With python Class definition, you are free to add your own methods, by the way.

class Resource(db.Model):
    # .... your existing code
    @staticmethod
    def customq(limit, offset):
        """This method returns an instance of flask_sqlalchemy.BaseQuery"""
        return Resource.query.filter_by(is_active=1).limit(limit).offset(offset)

Then your example code becomes:

@app.route('/resources', methods=['GET'])
def resources_get_all():
    get_limits()
    resources = []
    data = Resource.customq(LIMIT, OFFSET).all()

Here is the documentation on flask_sqlalchemy's BaseQuery

Upvotes: 4

Related Questions