【问题标题】:Flask SQLAlchemy query, specify column namesFlask SQLAlchemy 查询,指定列名
【发布时间】:2012-07-16 19:53:27
【问题描述】:

如何使用模型在查询中指定我想要的列(默认选择所有列)?我知道如何使用 sqlalchmey 会话来做到这一点:session.query(self.col1),但是如何使用模型来做到这一点?我做不到SomeModel.query()。有什么办法吗?

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    您可以使用with_entities() 方法来限制您希望在结果中返回哪些列。 (documentation)

    result = SomeModel.query.with_entities(SomeModel.col1, SomeModel.col2)
    

    根据您的要求,您可能还会发现deferreds 很有用。它们允许您返回完整的对象,但限制通过网络传输的列。

    【讨论】:

    • with_entities() 使 all() 产生列值的元组,而不是对象!
    • kolypto:它会产生任何你要求它产生的东西。 SomeModel.query.with_entities(SomeModel) 会产生对象。就像 session.query(SomeModel.col1, SomeModel.col2) 会产生列值的元组一样。如果您不希望列通过网络传输,则可以使用延迟,但无论如何您都想要整个对象。
    • 谢谢它的工作。但是我们如何为该字段分配别名?因为在我的情况下,我使用的是 JOIN 和冲突 ID 两个表中都存在的字段
    • 是的,我和@MitulShah 有同样的问题,如何设置别名?
    • 对于别名,请查看下面的简短答案,即。使用.label()stackoverflow.com/a/11535992/248616
    【解决方案2】:
    session.query().with_entities(SomeModel.col1)
    

    一样
    session.query(SomeModel.col1)
    

    对于别名,我们可以使用 .label()

    session.query(SomeModel.col1.label('some alias name'))
    

    【讨论】:

    • 第二个听起来更合乎逻辑,而且更短——win/win
    • 第一个(和第三个)选项是最好的,到目前为止,如果您想重用现有的查询对象,尤其是在执行多个复杂子查询的情况下。
    【解决方案3】:

    你可以使用load_only函数:

    from sqlalchemy.orm import load_only
    
    fields = ['name', 'addr', 'phone', 'url']
    companies = session.query(SomeModel).options(load_only(*fields)).all()
    

    【讨论】:

    • 这个解决方案是最好的,因为它仍然作为一个对象工作,而不仅仅是结果列表。
    • 感谢您提供此解决方案。它有很多优点: - 返回与.first().one() 完全相同类型的对象(这将延迟/急切加载字段和关系), - 可以设置为查询组件
    • 代码是干净的,但是 sql 查询选择了数据库中的所有字段。我在接受的答案中使用了with_entities,并且查询仅选择了该字段/。
    • 这会返回整个对象。
    • 这不起作用,正在返回整个对象。
    【解决方案4】:

    您可以使用Model.query,因为Model(或者通常是它的基类,尤其是在使用声明性扩展的情况下)被分配了Sesssion.query_property。在这种情况下,Model.query 等同于 Session.query(Model)

    我不知道修改查询返回的列的方法(使用add_columns() 添加更多列除外)。
    所以最好的办法是使用Session.query(Model.col1, Model.col2, ...)(如 Salil 所示)。

    【讨论】:

    • 我相信也可能有一种方法可以使用查询值()的列列表来做到这一点,docs.sqlalchemy.org/en/latest/orm/… - 但目前该列表的语法糖让我难以理解。跨度>
    【解决方案5】:

    您可以使用 Query.values,Query.values

    session.query(SomeModel).values('id', 'user')

    【讨论】:

      【解决方案6】:

      我一般用这个sn-p:

      fields = ["col1", "col2", ...]\
      session.query(map(lambda x: getattr(SomeModel.c, x), fields))
      

      【讨论】:

      • 我还是得用add_columns;不确定缺少什么,但这个想法很好。
      【解决方案7】:

      result = ModalName.query.add_columns(ModelName.colname, ModelName.colname)

      【讨论】:

      • 您能否为您的回答提供更多背景信息?为什么以及如何工作可以帮助其他有类似问题的人。谢谢!
      【解决方案8】:

      由于session.query(SomeModel.col1) 返回一个像[('value_1',),('value_2',)] 这样的元组数组,如果您想将结果转换为普通数组,您可以使用以下语句之一来实现:

      values = [value[0] for value in session.query(SomeModel.col1)]
      values = [model.col1 for model in session.query(SomeModel).options(load_only('col1'))]
      

      结果:

       ['value_1', 'value_2']
      

      【讨论】:

        【解决方案9】:

        这里有一个例子:

        movies = Movie.query.filter(Movie.rating != 0).order_by(desc(Movie.rating)).all()
        

        我在数据库中查询评分 0 的电影,然后按评分最高的顺序对它们进行排序。

        看这里:Select, Insert, Delete in Flask-SQLAlchemy

        【讨论】:

          猜你喜欢
          • 2013-07-24
          • 2013-04-12
          • 1970-01-01
          • 1970-01-01
          • 2019-04-23
          • 2019-12-13
          • 2017-08-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多