【问题标题】:Filter postgres JSON column by null value in SQLAlchemy在 SQLAlchemy 中按空值过滤 postgres JSON 列
【发布时间】:2015-06-01 07:30:57
【问题描述】:

所以我有一个这样的模型:

class myModel(Base):

    id = Column(Integer, primary_key=True)
    border = Column(JSONB)

如何查询没有边框的行?我试过了:

filter(myModel.border != None) #nope
filter(myModel.border != 'null') #nope
from sqlalchemy import null
filter(myModel.border != null()) #nope

该值显然作为"JSON encoded null value" 存储在postgres 中。它在实例化时肯定会被序列化回 python None,但我不知道如何查询它。看来您可以在列上设置none_as_null,即:

Column(JSONB(none_as_null=True))

它将 JSON 编码的 null 替换为 SQL 空值,但在所有列上都必须这样做似乎很奇怪。我在这里想念什么?

编辑:应该提到这是 sqlalchemy 的 v0.9.8

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    从 sqlalchemy>=0.7.9,您可以使用过滤运算符 .isnot 而不是像这样比较约束 - filter(myModel.border.isnot(None))

    要获取边框为空的模型,请执行filter(myModel.border.is_(None))

    【讨论】:

    • 这个只有在模型指定JSONB(none_as_null=True)JSON(none_as_null=True)时有效。见JSON.none_as_null
    【解决方案2】:

    PostgreSQL 有函数jsonb_typeof,返回字符串类型的json 值。因此,您可以将空值过滤为jsonb_typeof(myModel.border) != 'null'。 您可以在PostgreSQL documentation中找到详细信息

    【讨论】:

      【解决方案3】:

      这适用于 border 作为 JSON null 和 PostgreSQL NULL

      from sqlalchemy.sql.expression import text
      filter(myModel.border != text("'null'"))
      

      (用SQLAlchemy==1.1.14测试)

      【讨论】:

      • 不适用于 PostgreSQL 9.6 和 SQLAlchemy 1.1.x 或 1.2.x。它抛出了这个错误ProgrammingError: operator does not exist: json <> unknown HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 我成功地从 sqlalchemy 导入 null 并与null()进行比较@
      【解决方案4】:

      使用JSON.NULL。来自docs

      要插入或选择 SQL NULL 值,请使用常量 null()

      from sqlalchemy import null
      conn.execute(table.insert(), json_value=null())
      

      要插入或选择 JSON "null" 的值,请使用常量 JSON.NULL

      conn.execute(table.insert(), json_value=JSON.NULL)
      

      所以在你的情况下,

      from sqlalchemy import JSON
      
      myModel.query.filter(myModel.border != JSON.NULL)
      

      【讨论】:

        【解决方案5】:

        您将能够使用值 null() 来持久化它

        >>> from sqlalchemy import null
        
        >>> filter(myModel.border != null()) 
        

        【讨论】:

        • 它适用于我使用类型 sqlalchemy.dialects.postgresql.JSON 的 SQLAlchemy 1.1 或 1.2 和 PostgreSQL 9.6 虽然使用与 text("'null'") 进行比较的建议不起作用。
        猜你喜欢
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 2014-06-25
        • 2021-12-27
        • 2016-11-04
        • 1970-01-01
        • 2016-12-22
        • 1970-01-01
        相关资源
        最近更新 更多