【问题标题】:SQLAlchemy ? operator on JSONB keySQL炼金术? JSONB 键上的运算符
【发布时间】:2017-05-16 18:04:49
【问题描述】:

我有一个带有 JSONB 列的简单表。在该字段中,我有一个键:key,key 的值可以是带有["val1", "val2"] 的列表或单个字符串"val2"。

当key 中的值是"val2" 时,我得到了一个原始 SQL 查询:

SELECT t.c FROM t WHERE t.c->'key' ? "val2"

但是,我正在努力在 SQLAlchemy 查询中复制它:

我有一个session

query = session.query(t).filter(t.c.has_key('val2'))

导致

SELECT t.c FROM t WHERE t.c ? 'val2' 但我希望 ? 运算符在 -> 上。

获得->(据我所知)的唯一方法是使用filter(t.c['key2'])。但是,然后我无法执行has_key() 我得到:

AttributeError: Neither 'JSONElement' object nor 'Comparator' object has an attribute 'has_key'

有什么想法吗?

【问题讨论】:

  • 虽然可能不是最佳选择,但您可以使用 filter(t.c['key2'].op('?')('val2')) 解决此问题,或更新您的 SQLAlchemy。在这种情况下,较新的版本可以正常工作。
  • 或:filter(t.c['key'].has_key('val2'))
  • @IljaEverilä 不错,您能否将其添加为答案,我会接受。谢谢。

标签: python sqlalchemy


【解决方案1】:

旧版本的 SQLAlchemy 的 JSONB 列在项目访问时生成 JSONElement 对象,这些对象似乎缺少某些 json 比较器方法,例如 has_key()。 JSONB 类型是在 1.0 版本中引入并向后移植到 0.9.7,但我认为 this was fixed in 1.1。同时,如果您无法升级 SQLAlchemy,您可以使用 generic op() operator function 解决此问题:

query = session.query(t).\
    filter(t.c['key2'].op('?')('val2'))

当你最终设法升级时,你可以

filter(t.c['key2'].has_key('val2'))

正如预期的那样。

【讨论】:

  • 很好的现场版本,使用的是 1.0.17。但很高兴了解.op()。
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 2016-09-27
  • 2016-12-25
  • 2016-10-02
  • 1970-01-01
  • 2019-08-02
相关资源
最近更新 更多