简体   繁体   中英

Filter postgres JSON column by null value in SQLAlchemy

So I've got a model like such:

class myModel(Base):

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

How can I query for rows that don't have a border? I've tried:

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

The value is apparently stored in postgres as a "JSON encoded null value" . Its definitely getting serialized back to a python None when instantiated, but I have no idea how to query against it. It looks like you can set none_as_null on the column, ie:

Column(JSONB(none_as_null=True))

Which replaces the JSON encoded null with a SQL null, but that seems strange to have to do on all columns. What am I missing here?

edit: should mention this is v0.9.8 of sqlalchemy

from sqlalchemy>=0.7.9, you could use the filter operator .isnot instead of comparing constraints like this - filter(myModel.border.isnot(None))

To get models with border nulls, do filter(myModel.border.is_(None))

PostgreSQL has function jsonb_typeof , that returns string type of json value. So you can filter null values as jsonb_typeof(myModel.border) != 'null' . You can find details in the PostgreSQL documentation

This works for both border as JSON null and PostgresQL NULL :

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

(tested with SQLAlchemy==1.1.14 )

Use JSON.NULL . From the docs :

To insert or select against a value that is SQL NULL, use the constant null() :

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

To insert or select against a value that is JSON "null" , use the constant JSON.NULL :

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

So in your case,

from sqlalchemy import JSON

myModel.query.filter(myModel.border != JSON.NULL)

you will be able to persist this using the value null()

>>> from sqlalchemy import null

>>> filter(myModel.border != null()) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM