【问题标题】:Query a specific JSON column (postgres) with sqlalchemy使用 sqlalchemy 查询特定的 JSON 列(postgres)
【发布时间】:2018-01-23 04:13:57
【问题描述】:

我有一个带有 JSON 字段的模型:

class Item(db.Model)
   ...
   data = db.Column(JSON, nullable=False)
   ...

数据中包含一些 JSON,例如:

{
    "cost": 10.00,
    "passengers": 2,
    "surcharge": 1.6
}

我希望能够使用过滤器获得表中所有行的成本总和。我尝试了以下方法,但似乎没有用。

db.session.query(func.count(Item.data['cost'])).filter(
          Item.data["surcharge"].cast(Float) > 1
      ).scalar()

【问题讨论】:

    标签: python json postgresql flask sqlalchemy


    【解决方案1】:

    您使用了错误的aggregatecount(expression) 计算 表达式 不为空的行数。如果你想要一个总和,请使用sum(expression)

    db.session.query(func.sum(Item.data['cost'].astext.cast(Numeric))).\
        filter(Item.data['surcharge'].astext.cast(Numeric) > 1).\
        scalar()
    

    请注意,由于binary floats not being able to represent all decimal values,货币值和二进制浮点数学是一种糟糕的混合。而是使用正确的monetary typeNumeric,在这种情况下,SQLAlchemy 使用Decimal 在 Python 中表示结果。

    【讨论】:

    • 虽然 PostgreSQL JSONB 将数字存储为数字,而 JSON 存储为十进制字符串...但是,需要使用 Python 进行一些特殊处理...
    • 很好的答案,但我不得不使用 as_string() 而不是 astext (SQLAlchemy 1.3.23)
    【解决方案2】:

    您需要使用Float 而不是Integer 作为cast 的参数

    db.session.query(func.count(Item)).filter(
              Item.data['surcharge'].cast(Float) > 1
          ).all()
    

    【讨论】:

    • 公平点,我已经更新了查询,但仍然无法正常工作。它只返回 0。
    猜你喜欢
    • 2016-12-01
    • 2020-03-10
    • 2016-12-22
    • 1970-01-01
    • 2022-01-23
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    相关资源
    最近更新 更多