Skip to content

Instantly share code, notes, and snippets.

@jennielees
Created March 14, 2015 21:56
Show Gist options
  • Save jennielees/b8f6f03e6fa39e9f0f16 to your computer and use it in GitHub Desktop.
Save jennielees/b8f6f03e6fa39e9f0f16 to your computer and use it in GitHub Desktop.
Flask-SQLAlchemy Overrides

This was going to be an answer to pallets-eco/flask-sqlalchemy#269 but I realised I was getting further away from answering the actual question.

How to make SQLAlchemy models that are reusable, and compatible with Flask-SQLAlchemy

I looked into doing something similar, in order to use SQLAlchemy models outside the app context and to automatically use some mixins for all models created, as well as to override the default table naming scheme.

Worth noting there are some unmerged PRs around overriding the metadata/base: pallets-eco/flask-sqlalchemy#61

The Model and BaseQuery classes are standalone -- it doesn't look like they require the instantiation, so you could import and inherit from them, or rewrite them to support what you need. The issue is then pulling your custom classes back into the SQLAlchemy() part, since the class names are hardcoded.

What I ended up doing:

  • Create custom Model subclass (also inheriting from the mixins I wanted to use)
  • Create custom SQLAlchemy subclass, reimplementing make_declarative_base, using existing BaseQuery (but I'm pretty sure you could extend that the same way)
class Model(AutoTimestampMixin, AutoIDMixin):
    query_class = BaseQuery
    query = None

    @declared_attr
    def __tablename__(cls):
        return cls.__name__.lower()


class SelfNamingSQLAlchemy(SQLAlchemy):
    def make_declarative_base(self):
        base = declarative_base(cls=Model, name='Model',
                                metaclass=_BoundDeclarativeMeta)
        base.query = _QueryProperty(self)
        return base
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment