declarative_base() 和 db.Model 有啥区别?

Posted

技术标签:

【中文标题】declarative_base() 和 db.Model 有啥区别?【英文标题】:What is the difference between the declarative_base() and db.Model?declarative_base() 和 db.Model 有什么区别? 【发布时间】:2014-05-07 01:37:26 【问题描述】:

Flask-SQLAlchemy 插件的quickstart tutorial 指示用户创建继承db.Model 类的表模型,例如

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

但是,SQLAlchemy tutorial 和bottle-SQLAlchemy README 都表明表模型继承了从declarative_base() 实例化的Base

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

这两种方法有什么区别?

【问题讨论】:

【参考方案1】:

查看 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()

我相信这些是唯一的区别。

【讨论】:

我今天只是在寻找这个我已经构建了一年左右的应用程序,最初基于您的“Mega Flask Tutorial”,它使用 db.Model 而不是显式使用 Base =声明式_Base。我很困惑,因为我的模型都清楚地使用了声明式扩展,但我从未调用过 declarative_base()。感谢您的精彩解释! 是否可以在一个用户模型中使用 db.Model 并在地址模型中使用 Base。例如:- class User(db.Model), class Address(Base)? 不确定,但我猜有些事情是行不通的。 Flask-SQLAlchemy 在 db.Model 类的基础上添加了一些行为,因此任何直接从声明性基础继承的模型都不会拥有。

以上是关于declarative_base() 和 db.Model 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQLAlchemy declarative_base() 在 VS Code 中“继承'Base',它不是一个类”

mongo常用操作

数据库定时备份

逻辑回归的梯度下降计算

sqlalchemy的使用

sqlalchemy 相关