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?
The declarative_base() base class contains a MetaData object where newly defined Table objects are collected. This object is intended to be accessed directly for MetaData -specific operations. Such as, to issue CREATE statements for all tables: engine = create_engine('sqlite://') Base.
An application describes the kinds of data it uses with models. A model is a Python class that inherits from the Model class. The model class defines a new Kind of datastore entity and the properties the Kind is expected to take. The Kind name is defined by the instantiated class name that inherits from db.
One of which is that Flask-SQLAlchemy has its own API. This adds complexity by having its different methods for ORM queries and models separate from the SQLAlchemy API. Another disadvantage is that Flask-SQLAlchemy makes using the database outside of a Flask context difficult.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With