如何查询 JSON 元素
How to query a JSON element
假设我有一个 Postgres 数据库 (9.3) 并且有一个名为 Resources
的 table。在 Resources
table 我有字段 id
是一个 int 和 data
这是一个 JSON 类型。
假设我在 table.
中有以下记录
- 1, {'firstname':'Dave', 'lastname':'Gallant'}
- 2, {'firstname':'John', 'lastname':'Doe'}
我想要做的是编写一个查询,该查询将 return 数据列中具有 json 元素且姓氏等于 "Doe"[=16] 的所有记录=]
我试过这样写:
records = db_session.query(Resource).filter(Resources.data->>'lastname' == "Doe").all()
Pycharm 但是在“->>”
上给我一个编译错误
有谁知道我将如何编写过滤器子句来完成我需要的事情?
尝试使用 astext
records = db_session.query(Resource).filter(
Resources.data["lastname"].astext == "Doe"
).all()
请注意,该列的类型必须为 JSONB。常规 JSON 列将不起作用。
您也可以将字符串显式转换为 JSON(请参阅 Postgres JSON type doc)。
from sqlalchemy.dialects.postgres import JSON
from sqlalchemy.sql.expression import cast
db_session.query(Resource).filter(
Resources.data["lastname"] == cast("Doe", JSON)
).all()
根据sqlalchemy.types.JSON,你可以这样做
from sqlalchemy import JSON
from sqlalchemy import cast
records = db_session.query(Resource).filter(Resources.data["lastname"] == cast("Doe", JSON)).all()
如果您使用的是 JSON 类型(而不是 JSONB),以下对我有用:
注意 '"object"'
query = db.session.query(ProductSchema).filter(
cast(ProductSchema.ProductJSON["type"], db.String) != '"object"'
)
我在 JSON(不是 JSONB)类型的列中有一些 GeoJSON,现有解决方案中的 none 有效,但事实证明,在版本 1.3.11 中添加了一些新的数据转换器,所以现在您可以:
records = db_session.query(Resource).filter(Resources.data["lastname"].as_string() == "Doe").all()
参考:https://docs.sqlalchemy.org/en/14/core/type_basics.html#sqlalchemy.types.JSON
Casting JSON Elements to Other Types
Index operations, i.e. those invoked by calling upon the expression
using the Python bracket operator as in some_column['some key'],
return an expression object whose type defaults to JSON by default, so
that further JSON-oriented instructions may be called upon the result
type. However, it is likely more common that an index operation is
expected to return a specific scalar element, such as a string or
integer. In order to provide access to these elements in a
backend-agnostic way, a series of data casters are provided:
Comparator.as_string() - return the element as a string
Comparator.as_boolean() - return the element as a boolean
Comparator.as_float() - return the element as a float
Comparator.as_integer() - return the element as an integer
These data casters are implemented by supporting dialects in order to
assure that comparisons to the above types will work as expected, such
as:
# integer comparison
data_table.c.data["some_integer_key"].as_integer() == 5
# boolean comparison
data_table.c.data["some_boolean"].as_boolean() == True
根据this,1.3.11 之前的版本,最稳健的方法应该是这样的,因为它适用于多种数据库类型,例如SQLite,MySQL,Postgres:
from sqlalchemy import cast, JSON, type_coerce, String
db_session.query(Resource).filter(
cast(Resources.data["lastname"], String) == type_coerce("Doe", JSON)
).all()
从 1.3.11 版本开始,特定类型的脚轮是处理这个问题的新的更简洁的方法:
db_session.query(Resource).filter(
Resources.data["lastname"].as_string() == "Doe"
).all()
假设我有一个 Postgres 数据库 (9.3) 并且有一个名为 Resources
的 table。在 Resources
table 我有字段 id
是一个 int 和 data
这是一个 JSON 类型。
假设我在 table.
中有以下记录- 1, {'firstname':'Dave', 'lastname':'Gallant'}
- 2, {'firstname':'John', 'lastname':'Doe'}
我想要做的是编写一个查询,该查询将 return 数据列中具有 json 元素且姓氏等于 "Doe"[=16] 的所有记录=]
我试过这样写:
records = db_session.query(Resource).filter(Resources.data->>'lastname' == "Doe").all()
Pycharm 但是在“->>”
上给我一个编译错误有谁知道我将如何编写过滤器子句来完成我需要的事情?
尝试使用 astext
records = db_session.query(Resource).filter(
Resources.data["lastname"].astext == "Doe"
).all()
请注意,该列的类型必须为 JSONB。常规 JSON 列将不起作用。
您也可以将字符串显式转换为 JSON(请参阅 Postgres JSON type doc)。
from sqlalchemy.dialects.postgres import JSON
from sqlalchemy.sql.expression import cast
db_session.query(Resource).filter(
Resources.data["lastname"] == cast("Doe", JSON)
).all()
根据sqlalchemy.types.JSON,你可以这样做
from sqlalchemy import JSON
from sqlalchemy import cast
records = db_session.query(Resource).filter(Resources.data["lastname"] == cast("Doe", JSON)).all()
如果您使用的是 JSON 类型(而不是 JSONB),以下对我有用:
注意 '"object"'
query = db.session.query(ProductSchema).filter(
cast(ProductSchema.ProductJSON["type"], db.String) != '"object"'
)
我在 JSON(不是 JSONB)类型的列中有一些 GeoJSON,现有解决方案中的 none 有效,但事实证明,在版本 1.3.11 中添加了一些新的数据转换器,所以现在您可以:
records = db_session.query(Resource).filter(Resources.data["lastname"].as_string() == "Doe").all()
参考:https://docs.sqlalchemy.org/en/14/core/type_basics.html#sqlalchemy.types.JSON
Casting JSON Elements to Other Types
Index operations, i.e. those invoked by calling upon the expression using the Python bracket operator as in some_column['some key'], return an expression object whose type defaults to JSON by default, so that further JSON-oriented instructions may be called upon the result type. However, it is likely more common that an index operation is expected to return a specific scalar element, such as a string or integer. In order to provide access to these elements in a backend-agnostic way, a series of data casters are provided:
Comparator.as_string() - return the element as a string Comparator.as_boolean() - return the element as a boolean Comparator.as_float() - return the element as a float Comparator.as_integer() - return the element as an integer
These data casters are implemented by supporting dialects in order to assure that comparisons to the above types will work as expected, such as:
# integer comparison data_table.c.data["some_integer_key"].as_integer() == 5 # boolean comparison data_table.c.data["some_boolean"].as_boolean() == True
根据this,1.3.11 之前的版本,最稳健的方法应该是这样的,因为它适用于多种数据库类型,例如SQLite,MySQL,Postgres:
from sqlalchemy import cast, JSON, type_coerce, String
db_session.query(Resource).filter(
cast(Resources.data["lastname"], String) == type_coerce("Doe", JSON)
).all()
从 1.3.11 版本开始,特定类型的脚轮是处理这个问题的新的更简洁的方法:
db_session.query(Resource).filter(
Resources.data["lastname"].as_string() == "Doe"
).all()