【问题标题】:Getting first row from sqlalchemy从 sqlalchemy 获取第一行
【发布时间】:2013-08-09 05:19:36
【问题描述】:

我有以下疑问:

profiles = session.query(profile.name).filter(and_(profile.email == email, profile.password == password_hash))

如何检查是否有一行以及如何只返回第一行(如果有匹配则应该只有一个)?

【问题讨论】:

    标签: python sqlalchemy flask flask-sqlalchemy


    【解决方案1】:

    使用query.one() 得到一个,正是一个结果。在所有其他情况下,它将引发您可以处理的异常:

    from sqlalchemy.orm.exc import NoResultFound
    from sqlalchemy.orm.exc import MultipleResultsFound
    
    try:
        user = session.query(User).one()
    except MultipleResultsFound, e:
        print e
        # Deal with it
    except NoResultFound, e:
        print e
        # Deal with that as well
    

    还有query.first(),它只会为您提供可能很多的第一个结果,而不会引发这些异常。但是既然你要处理没有结果或者超出你想象的情况,那么query.one()正是你应该使用的。

    【讨论】:

    • 谢谢!不过还有另一个小问题。我添加了profile.name,它只给了我一个元组......
    • 是的,当您专门要求使用 query(Class.attr) 映射类的列时,SQLAlchemy 将返回 sqlalchemy.util._collections.NamedTuple 而不是 DB 对象。
    • 请注意,first() 应用了一个 LIMIT,这取决于查询的复杂性,它可能会将较大查询的一部分变成一个子选择,其他所有内容都会被 JOINed 反对。
    • 是否可以从flask-sqlalchemy(给定db = SQLAlchemy(app))导入异常,还是必须像您一样直接导入?
    • @Tjorriemorrie 您确实需要从sqlalchemy 导入它们。 flask-sqlalchemy 模块只是 Flask 的一个集成包,它不继承或包装任何 sqlalchemy 的异常。
    【解决方案2】:

    您可以在查询对象上使用first() 函数。这将返回第一个结果,如果没有结果,则返回 None。

    result = session.query(profile.name).filter(...).first()
    
    if not result:
        print 'No result found'
    

    您也可以使用one(),它会为您提供唯一的项目,但会引发针对零个或多个结果的查询的异常。

    from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
    try:
        result = session.query(profile.name).filter(...).one()
        print result
    except NoResultFound:
        print 'No result was found'
    except MultipleResultsFound:
        print 'Multiple results were found'
    

    【讨论】:

    • 刚刚注意到第二个except 中有一个错字 - MultipleResultsFound。想更新吗?
    • @Hussain:除了是正确的,因为one() 只期望一个结果,并创建了涵盖两种可能性(无和许多)的例外。根据以下答案,one_or_none() 会将输出限制为一个(或无),从而使此异常变得多余。
    【解决方案3】:

    使用one_or_none()。最多返回一个结果或引发异常。

    如果查询未选择任何行,则返回 None。

    【讨论】:

    • 值得一提的是,这是《1.0.9版新增:新增Query.one_or_none()》
    【解决方案4】:

    假设你有一个模型用户,你可以得到第一个结果:

    User.query.first()

    如果表为空,则返回 None。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-25
      • 2014-12-19
      • 2019-03-09
      • 2016-03-14
      • 2011-08-13
      • 2021-03-29
      • 1970-01-01
      • 2015-11-25
      相关资源
      最近更新 更多