2016-03-28 16 views
0

migrierten Spaltentyp von HSTORE bis JSONB und ist mit diesem Code-Snippet ...Kann nicht Array von ganzen Zahlen in Postgres Abfrage

from sqlalchemy.dialects.postgresql import ARRAY, JSONB 

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

und sind immer diese Fehlermeldung ...

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"] ist ein Array von ganzen Zahlen und ich versuche einfach alle Zeilen abzufragen, die eine bestimmte ganze Zahl enthalten.

Auch .cast() funktioniert perfekt in der gleichen Spalte, wenn Integer Aufruf ...

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

Sie ohne das 'cast' dh' Candidate.bio Versuchen [ "employment_type"]. Enthält (employment_type) '? Von den Dokumenten aus sollte "contains" auch für Arrays funktionieren - "Testen, ob Schlüssel (oder Array) eine Obermenge von/enthalten die Schlüssel des Arguments jsonb Ausdruck." –

+0

@LymanZerga Yup, versucht ohne die Besetzung ... Ich bekomme DataError: (psycopg2.DataError) ungültige Eingabesyntax für Integer: "%" LINE 3: ...! = 0 UND ((kandidaten.bio -> 'location_work ') LIKE'% '+ 2 || ... –

+0

können Sie einige Beispielzeilen von Daten. –

Antwort

1

SqlAlchemy ist wahrscheinlich Schwierigkeiten bei der Konstruktion der where Klausel, weil es kann nicht herausfinden, welcher Typ bio->'employment_type' ist.

Wenn die contains Methode von einem String Objekt aufgerufen wird, wäre es eine LIKE Klausel, erzeugt aber für JSONB oder ARRAY es müßte die @> Betreiber generieren.

geben sqlalchemy die notwendigen Hinweise, explizites Casting überall verwenden, also schreiben Sie Ihre Abfrage wie

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)) 
+0

Dies funktionierte, danke! –

+0

@Suraj Kapoor Sie müssen nicht Beschäftigungstyp zu JSONB. – RazerM

+0

@SurajKapoor, thanks Ich habe gerade versucht, und auf meinem Rechner, war keine Umwandlung notwendig, wenn eine Liste an contains übergeben wurde, aber eine ganze Zahl erforderlich Casting. Welche Version von sqlalchemy/Python verwenden Sie? Ich bin auf Python 3.4.3 sqlalchemy 1.0.11 –

0

In meinem Beispiel habe ich eine JSONB Spalte bio mit folgenden Daten genannt:

{"employment_type": [1, 2, 3]} 

Edit: Casting zu JSONB Werke:

>>> 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]} 

Ursprüngliche Antwort:

konnte ich nicht .contains bekommen auf Candidate.bio['employment_type'] zu arbeiten, aber wir können das Äquivalent der folgenden SQL tun:

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

wie folgt aus:

>>> employment_type = 2 
>>> test = {'employment_type': [employment_type]} 

>>> query = (
...  session.query(Candidate) 
...  .filter(Candidate.bio.contains(test))) 

>>> query.one().bio 
{"employment_type": [1, 2, 3]} 
Verwandte Themen