在元数据库 SQL 查询中提取 JSON 内容
Extract JSON content in Metabase SQL query
使用:Django==2.2.24
、Python=3.6
、PostgreSQL 是底层数据库
使用 Django ORM,我可以轻松地进行各种查询,但我开始使用 Metabase,我的 SQL 可能有点生疏。
问题:
我正在尝试获取列表中项目的计数,在字典中的一个键下,存储为 JSONField
:
from django.db import models
from jsonfield import JSONField
class MyTable(models.Model):
data_field = JSONField(blank=True, default=dict)
存储在data_field
中的字典示例:
{..., "my_list": [{}, {}, ...], ...}
在"my_list"
键下,存储的值是一个列表,其中包含一些其他字典。
在 Metabase 中,我试图计算列表中字典的数量,但更基本的东西,none 其中有效。
我试过的一些东西:
尝试:
SELECT COUNT(elem->'my_list') as my_list_count
FROM my_table, json_object_keys(data_field:json) AS elem
错误:
ERROR: syntax error at or near ":" Position: 226
尝试:
SELECT ARRAY_LENGTH(elem->'my_list') as my_list_count
FROM my_table, JSON_OBJECT_KEYS(data_field:json) AS elem
错误:
ERROR: syntax error at or near ":" Position: 233
尝试:
SELECT JSON_ARRAY_LENGTH(data_field->'my_list'::json)
FROM my_table
错误:
ERROR: invalid input syntax for type json Detail: Token "my_list" is invalid. Position: 162 Where: JSON data, line 1: my_list
尝试:
SELECT ARRAY_LENGTH(JSON_QUERY_ARRAY(data_field, '$.my_list'))
FROM my_table
错误:
ERROR: function json_query_array(text, unknown) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 140
基本上,我认为问题是我在尝试使用的方法中使用了错误的签名(大部分时间)。
我使用这个查询来确保我至少可以从字典中获取键:
SELECT JSON_OBJECT_KEYS(data_field::json)
FROM my_table
我无法在不添加 ::json
强制转换的情况下使用 JSON_OBJECT_KEYS()
,我遇到了这个错误:
ERROR: function json_object_keys(text) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 127
但是通过 json 转换,我得到了预期的所有键。
感谢您的观看!
编辑:
我也发现了这个 interesting article with different solution 但 none 的解决方案有效。
还看到 没有帮助。
好的,在进一步挖掘之后,我找到了 this 篇文章,其中有正确的 format/syntax。
这段代码是我用来从 JSON 对象中成功获取列表的代码:
select data_field::json->'my_list' as the_list
from my_table
然后,我用json_array_length()
得到元素个数:
select json_array_length(data_field::json->'my_list') as number_of_elements
from my_table
大功告成! :)
编辑:
我刚刚找到了整个恶作剧的原因。
在代码中(几年前)我们使用了这个包:
jsonfield==1.0.3
并这样使用:
from jsonfield import JSONField
问题是在后台,Postgres 将数据保存为字符串,因此需要将其转换为 JSON。
后来 Django 引入了它自己的 JSONField
,它可以像你期望的那样存储数据,而不需要强制转换:
from django.contrib.postgres.fields import JSONField
使用:Django==2.2.24
、Python=3.6
、PostgreSQL 是底层数据库
使用 Django ORM,我可以轻松地进行各种查询,但我开始使用 Metabase,我的 SQL 可能有点生疏。
问题:
我正在尝试获取列表中项目的计数,在字典中的一个键下,存储为 JSONField
:
from django.db import models
from jsonfield import JSONField
class MyTable(models.Model):
data_field = JSONField(blank=True, default=dict)
存储在data_field
中的字典示例:
{..., "my_list": [{}, {}, ...], ...}
在"my_list"
键下,存储的值是一个列表,其中包含一些其他字典。
在 Metabase 中,我试图计算列表中字典的数量,但更基本的东西,none 其中有效。
我试过的一些东西:
尝试:
SELECT COUNT(elem->'my_list') as my_list_count
FROM my_table, json_object_keys(data_field:json) AS elem
错误:
ERROR: syntax error at or near ":" Position: 226
尝试:
SELECT ARRAY_LENGTH(elem->'my_list') as my_list_count
FROM my_table, JSON_OBJECT_KEYS(data_field:json) AS elem
错误:
ERROR: syntax error at or near ":" Position: 233
尝试:
SELECT JSON_ARRAY_LENGTH(data_field->'my_list'::json)
FROM my_table
错误:
ERROR: invalid input syntax for type json Detail: Token "my_list" is invalid. Position: 162 Where: JSON data, line 1: my_list
尝试:
SELECT ARRAY_LENGTH(JSON_QUERY_ARRAY(data_field, '$.my_list'))
FROM my_table
错误:
ERROR: function json_query_array(text, unknown) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 140
基本上,我认为问题是我在尝试使用的方法中使用了错误的签名(大部分时间)。
我使用这个查询来确保我至少可以从字典中获取键:
SELECT JSON_OBJECT_KEYS(data_field::json)
FROM my_table
我无法在不添加 ::json
强制转换的情况下使用 JSON_OBJECT_KEYS()
,我遇到了这个错误:
ERROR: function json_object_keys(text) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 127
但是通过 json 转换,我得到了预期的所有键。
感谢您的观看!
编辑:
我也发现了这个 interesting article with different solution 但 none 的解决方案有效。
还看到
好的,在进一步挖掘之后,我找到了 this 篇文章,其中有正确的 format/syntax。
这段代码是我用来从 JSON 对象中成功获取列表的代码:
select data_field::json->'my_list' as the_list
from my_table
然后,我用json_array_length()
得到元素个数:
select json_array_length(data_field::json->'my_list') as number_of_elements
from my_table
大功告成! :)
编辑:
我刚刚找到了整个恶作剧的原因。
在代码中(几年前)我们使用了这个包:
jsonfield==1.0.3
并这样使用:
from jsonfield import JSONField
问题是在后台,Postgres 将数据保存为字符串,因此需要将其转换为 JSON。
后来 Django 引入了它自己的 JSONField
,它可以像你期望的那样存储数据,而不需要强制转换:
from django.contrib.postgres.fields import JSONField