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',它不是一个类”