只是好奇我什么时候想要使用一个与另一个.他们有什么不同?
我们设置了系统,以便我们可以这样做:
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,查询的结果都不会改变,因此两者是等价的.
这两行是一回事.只有例外情况有所不同 实际上,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,查询的结果都不会改变,因此两者是等价的.
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.