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

114

Flask-SQLAlchemy插件的快速入门教程指导用户创建继承db.Model类的表模型。

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

然而,SQLAlchemy 教程和 bottle-SQLAlchemy README 都建议表模型应该继承自从 declarative_base() 实例化出来的 Base

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

这两种方法有什么不同之处?

1个回答

118

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

我认为这些是唯一的区别。


1
我今天刚好在为我已经建了一年左右的应用程序搜索这个内容,最初是基于你的“Mega Flask Tutorial”构建的,该教程使用db.Model而不是显式地使用Base = Declarative_Base。我感到困惑,因为我的模型明显都使用了Declarative扩展,但我从未调用过declarative_base()。感谢您提供的清晰解释! - Chockomonkey
在一个用户模型中使用db.Model和在地址模型中使用Base是可能的吗?例如:class User(db.Model),class Address(Base)。 - Saif ali Karedia
我不确定,但我猜有些事情可能无法正常工作。Flask-SQLAlchemy 在 db.Model 类中添加了一些行为,因此直接从声明基类继承的任何模型都不会具备这些行为。 - Miguel Grinberg
如果你在使用 Flask-SQLAlchemy,那么请使用 db.Model。如果你直接使用 SQLAlchemy,请使用 declarative_base。@KarishmaSukhwani - Miguel Grinberg
对于任何像我一样想知道的人,你可能正在寻找的“metadata”隐藏在“db.metadata”下面。 - lababidi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接