Customizing

Flask-SQLAlchemy defines sensible defaults. However, sometimes customization is needed. Two major pieces to customize are the Model base class and the default Query class.

Both of these customizations are applied at the creation of the SQLAlchemy object and extend to all models derived from its Model class.

Model Class

Flask-SQLAlchemy allows defining a custom declarative base, just like SQLAlchemy, that all model classes should extend from. For example, if all models should have a custom __repr__ method:

from flask_sqlalchemy import Model  # this is the default declarative base
from flask_sqlalchemy import SQLAlchemy

class ReprBase(Model):
     def __repr__(self):
         return "<{0} id: {1}>".format(self.__class__.__name__, self.id)

db = SQLAlchemy(model_class=ReprBase)

class MyModel(db.Model):
    ...

Note

While not strictly necessary to inherit from flask_sqlalchemy.Model it is encouraged as future changes may cause incompatibility.

Note

If behavior is needed in only some models, not all, a better strategy is to use a Mixin, as exampled below.

While this particular example is more useful for debugging, it is possible to provide many augmentations to models that would otherwise be achieved with mixins instead. The above example is equivalent to the following:

class ReprBase(object):
    def __repr__(self):
        return "<{0} id: {1}>".format(self.__class__.__name__, self.id)

db = SQLAlchemy()

class MyModel(db.Model, ReprBase):
    ...

It also possible to provide default columns and properties to all models as well:

from flask_sqlalchemy import Model, SQLAlchemy
from sqlalchemy import Column, DateTime
from datetime import datetime

class TimestampedModel(Model):
    created_at = Column(DateTime, default=datetime.utcnow)

db = SQLAlchemy(model_class=TimestampedModel)

class MyModel(db.Model):
    ...

All model classes extending from db.Model will now inherit a created_at column.

Query Class

It is also possible to customize what is availble for use on the special query property of models. For example, providing a get_or method:

from flask_sqlalchemy import BaseQuery, SQLAlchemy

class GetOrQuery(BaseQuery):
    def get_or(self, ident, default=None):
        return self.get(ident) or default

db = SQLAlchemy(query_class=GetOrQuery)

And now all queries executed from the special query property on Flask-SQLAlchemy models can use the get_or method as part of their queries. All relationships defined with db.relationship (but not sqlalchemy.relationship()) will also be provided with this functionality.

Warning

Unlike a custom Model base class, it is required to either inherit from either flask_sqlalchemy.BaseQuery or sqlalchemy.orm.Query() in order to define a custom query class.

It also possible to define a custom query class for individual relationships as well, by providing the query_class keyword in the definition. This works with both db.relationship and sqlalchemy.relationship:

class MyModel(db.Model):
    cousin = db.relationship('OtherModel', query_class=GetOrQuery)

Note

If a query class is defined on a relationship, it will take precedence over the query class attached to its corresponding model.

It is also possible to define a specific query class for individual models by overriding the query_class class attribute on the model:

class MyModel(db.Model):
    query_class = GetOrQuery

In this case, the get_or method will be only availble on queries orginating from MyModel.query.