declarative_base() 和 db.Model 有什么区别?

115 投票
1 回答
21433 浏览
提问于 2025-04-18 00:13

Flask-SQLAlchemy 插件的 快速入门教程 指导用户创建表模型时要继承 db.Model 类,比如这样:

app = Flask(__main__)
db = SQLAlchemy(app)
class Users(db.Model):
    __tablename__ = 'users'
    ...

但是,SQLAlchemy 教程 和 bottle-SQLAlchemy 的 自述文件 都建议表模型应该继承一个从 declarative_base() 创建的 Base 类。

Base = declarative_base()
class Users(Base):
    __tablename__ = 'users'
    ...

这两种方法有什么区别呢?

1 个回答

120

在Flask-SQLAlchemy的源代码中,db.Model类是这样初始化的:

self.Model = self.make_declarative_base()

这里是make_declarative_base()方法:

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

_BoundDeclarativeMeta这个元类是SQLAlchemy的DeclarativeMeta的一个子类,它主要是为了支持计算__tablename__(表名)的默认值,并处理绑定。

base.query属性让基于Flask-SQLAlchemy的模型可以通过Model.query来访问查询对象,而不是使用SQLAlchemy的session.query(Model)

_QueryProperty查询类也是从SQLAlchemy的查询类继承而来的。Flask-SQLAlchemy的这个子类增加了三个在SQLAlchemy中不存在的查询方法:get_or_404()first_or_404()paginate()

我认为这就是它们之间唯一的区别。

撰写回答