当前位置:  开发笔记 > 编程语言 > 正文

何时使用SQLAlchemy .get()vs .filter(Foo.ID == primary_key_id).first()

如何解决《何时使用SQLAlchemy.get()vs.filter(Foo.ID==primary_key_id).first()》经验,为你挑选了2个好方法。

只是好奇我什么时候想要使用一个与另一个.他们有什么不同?

我们设置了系统,以便我们可以这样做:

my_user = User.query().filter(User.ID == 5).first()

要么

my_user = User.query().get(5)

Andrea Corbe.. 9

这两行是一回事.只有例外情况有所不同 实际上,get()是在上面实现的one().如果您filter()返回的结果超过了结果会有所不同,但在您的情况下确实不可能.

顺便说一句,SQL没有GET操作,它只有SELECT(带有可选的LIMIT).


sqlalchemy/orm/query.py :

def get(self, ident):
    ...
    return self._get_impl(ident, loading.load_on_ident)

sqlalchemy/orm/loading.py:

def load_on_ident(query, key,
                  refresh_state=None, lockmode=None,
                  only_load_props=None):
    ...
    try:
        return q.one()
    except orm_exc.NoResultFound:
        return None

q.one()反过来打电话q.one_or_none().

现在比较first()one_or_none():

def first(self):
    ...
    ret = list(self[0:1])
    if len(ret) > 0:
        return ret[0]
    else:
        return None


def one_or_none(self):
    ...
    ret = list(self)

    l = len(ret)
    if l == 1:
        return ret[0]
    elif l == 0:
        return None
    else:
        raise orm_exc.MultipleResultsFound(
            "Multiple rows were found for one_or_none()")

因此,first()使用LIMIT one_or_none()执行SELECT ,执行无限制的SELECT.但是,正如我们已经说过的,无论是否有LIMIT,查询的结果都不会改变,因此两者是等价的.



1> Andrea Corbe..:

这两行是一回事.只有例外情况有所不同 实际上,get()是在上面实现的one().如果您filter()返回的结果超过了结果会有所不同,但在您的情况下确实不可能.

顺便说一句,SQL没有GET操作,它只有SELECT(带有可选的LIMIT).


sqlalchemy/orm/query.py :

def get(self, ident):
    ...
    return self._get_impl(ident, loading.load_on_ident)

sqlalchemy/orm/loading.py:

def load_on_ident(query, key,
                  refresh_state=None, lockmode=None,
                  only_load_props=None):
    ...
    try:
        return q.one()
    except orm_exc.NoResultFound:
        return None

q.one()反过来打电话q.one_or_none().

现在比较first()one_or_none():

def first(self):
    ...
    ret = list(self[0:1])
    if len(ret) > 0:
        return ret[0]
    else:
        return None


def one_or_none(self):
    ...
    ret = list(self)

    l = len(ret)
    if l == 1:
        return ret[0]
    elif l == 0:
        return None
    else:
        raise orm_exc.MultipleResultsFound(
            "Multiple rows were found for one_or_none()")

因此,first()使用LIMIT one_or_none()执行SELECT ,执行无限制的SELECT.但是,正如我们已经说过的,无论是否有LIMIT,查询的结果都不会改变,因此两者是等价的.



2> osman..:

Andrea Corbellini的答案的一个重要补充: get如果SQLAlchemy会话中已存在对象,则可以通过从内存中检索对象来提高性能.

sqlalchemy/orm/query.py :

    :meth:`~.Query.get` is special in that it provides direct
    access to the identity map of the owning :class:`.Session`.
    If the given primary key identifier is present
    in the local identity map, the object is returned
    directly from this collection and no SQL is emitted,
    unless the object has been marked fully expired.
    If not present,
    a SELECT is performed in order to locate the object.

此外,如果对象已在会话中过期,get将执行数据库I/O(即SELECT语句)刷新对象:

sqlalchemy/orm/query.py :

    :meth:`~.Query.get` also will perform a check if
    the object is present in the identity map and
    marked as expired - a SELECT
    is emitted to refresh the object as well as to
    ensure that the row is still present.
    If not, :class:`~sqlalchemy.orm.exc.ObjectDeletedError` is raised.

推荐阅读
郑谊099_448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有