What is the difference between the declarative_base() and db.Model?

flask, flask-sqlalchemy, python, sqlalchemy

Solution

Looking in the Flask-SQLAlchemy source code the `db.Model` class is initialized as follows:

self.Model = self.make_declarative_base()

And here is the `make_declarative_base()` method:

def make_declarative_base(self):
    """Creates the declarative base."""
    base = declarative_base(cls=Model, name='Model',
                            metaclass=_BoundDeclarativeMeta)
    base.query = _QueryProperty(self)
    return base

The `_BoundDeclarativeMeta` metaclass is a subclass of SQLAlchemy's `DeclarativeMeta`, it simply adds support for computing a default value for `__tablename__` (the table name) and also to handle binds.

The `base.query` property enables Flask-SQLAlchemy based models to access a query object as `Model.query` instead of SQLAlchemy's `session.query(Model)`.

The `_QueryProperty` query class is also subclassed from SQLAlchemy's query. The Flask-SQLAlchemy subclass adds three additional query methods that do not exist in SQLAlchemy: `get_or_404()`, `first_or_404()` and `paginate()`.

I believe these are the only differences.

Problem

The quickstart tutorial for the Flask-SQLAlchemy plugin instructs users to create table models inheriting the `db.Model` class, e.g. ``` app = Flask(__main__) db = SQLAlchemy(app) class Users(db.Model): __tablename__ = 'users' ... ``` However, the SQLAlchemy tutorial and the bottle-SQLAlchemy README both suggest that table models inherit a `Base` instantiated from `declarative_base()`. ``` Base = declarative_base() class Users(Base): __tablename__ = 'users' ... ``` What is the difference between these two approaches?

Original source