无法在Postgres中查询整数数组

时间:2016-03-28 16:31:27

标签: arrays postgresql sqlalchemy

将列类型从HSTORE迁移到JSONB并使用此代码片段...

from sqlalchemy.dialects.postgresql import ARRAY, JSONB

if employment_type:
        base = base.filter(Candidate.bio["employment_type"].cast(ARRAY).contains(employment_type))  

我收到此错误......

127.0.0.1 - - [28/Mar/2016 12:25:13] "GET /candidate_filter/?employment_type_3=true HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/surajkapoor/Desktop/lhv-talenttracker/app/views.py", line 660, in investor_filter
    base = base.filter(Candidate.bio["employment_type"].cast(ARRAY).contains(employment_type))
  File "/Library/Python/2.7/site-packages/sqlalchemy/dialects/postgresql/json.py", line 93, in cast
    return self.astext.cast(type_)
  File "/Library/Python/2.7/site-packages/sqlalchemy/dialects/postgresql/json.py", line 95, in cast
    return sql.cast(self, type_)
  File "<string>", line 2, in cast

  File "/Library/Python/2.7/site-packages/sqlalchemy/sql/elements.py", line 2314, in __init__
    self.type = type_api.to_instance(type_)
  File "/Library/Python/2.7/site-packages/sqlalchemy/sql/type_api.py", line 1142, in to_instance
    return typeobj(*arg, **kw)
TypeError: __init__() takes at least 2 arguments (1 given)

Candidate.bio["employment_type"]是一个整数数组,我只是试图查询包含特定整数的所有行。

此外,.cast()在调用Integer时完全适用于同一列......

if internship:
    base = base.filter(Candidate.bio["internship"].cast(Integer) == 1)  

2 个答案:

答案 0 :(得分:1)

SqlAlchemy 可能很难构建where子句,因为它无法确定bio->'employment_type'的类型。

如果从contains对象调用String方法,它会生成LIKE子句,但对于JSONBARRAY,它需要生成@>运算符。

要为SqlAlchemy提供必要的提示,请在任何地方使用显式转换,即编写

之类的查询
from sqlalchemy import cast

if employment_type:
    casted_field = Candidate.bio['employment_type'].cast(JSONB)
    casted_values = cast(employment_type, JSONB)
    stmt = base.filter(casted_field.contains(casted_values))

答案 1 :(得分:0)

在我的示例中,我有一个名为JSONB的{​​{1}}列,其中包含以下数据:

bio

修改:投放到{"employment_type": [1, 2, 3]} 有效:

JSONB

原始回答:

我无法让>>> from sqlalchemy.dialects.postgresql import JSONB >>> employment_type = 2 >>> query = ( ... session.query(Candidate) ... .filter(Candidate.bio['employment_type'].cast(JSONB).contains(employment_type))) >>> query.one().bio {"employment_type": [1, 2, 3]} 使用.contains,但我们可以执行以下SQL的等效操作:

Candidate.bio['employment_type']
像这样:

SELECT * FROM candidate WHERE candidate.bio @> '{"employment_type": [2]}';