我有一个存储二维浮点数组的JSONB列。
{"field1": [[0.04735202492211838,0.48957828405235093 [0.42866042256355286,0.5729520320892334]], "field2": [[etc.],[etc.]]}
字段(键)始终具有相同的名称,数组(值)始终为[2] [2]。
问题:假设我使用Npgsql和Newtonsoft.JSON将上述JSON插入到我的JSONB列中,如下所示:
using Npgsql;
using NpgsqlTypes;
using Newtonsoft.Json;
...
conn = new NpgsqlConnection(...);
conn.Open();
template = new Dictionary<string, double[,]>();
// Not sure if this assignment actually conforms, just illustrative
template["field1"] = [[0.04735202492211838,0.48957828405235093],[0.42866042256355286,0.5729520320892334]]
template["field2"] = [[etc.],[etc.]] //not actual values of course
using (var cmd = new NpgsqlCommand("UPDATE JSONBTABLE SET JSONB_COL = @j WHERE JSONB_ID = @c", conn))
{
// Could it be an encoding issue with the string?
// doesn't makes sense, given impl of JSONB
string js = JsonConvert.SerializeObject(template);
cmd.Parameters.AddWithValue("j", NpgsqlDbType.Jsonb, js);
cmd.Parameters.AddWithValue("c", 1);
cmd.ExecuteNonQuery();
}
这会按预期更新值,没有任何看似错误。
如果我在Python中查询如下内容,问题就会变得明显
import psycopg2
from psycopg2.extras import Json
...
conn = psycopg2.connect(...)
cur = conn.cursor()
# for this example, our JSONBTABLE only has the record with the one column
cur.execute(
"""
SELECT JSONB_COL
FROM JSONBTABLE
WHERE JSONB_ID = %s
""", (1,)
)
cols = {column.name: i for i, column in enumerate(cur.description)}
row = cur.fetchone()
jsonb_dict = row[cols["JSONB_COL"]]
#jsonb_dict["field1"] == [[0.04735202492211838,0.48957828405235093],[0.42866042256355286,0.5729520320892334]]
#jsonb_dict["field2"] == [[etc.],[etc.]]
# Assuming that the JSONBTABLE has a column JSONB_ID as PK
cur.execute(
"""
SELECT JSONB_ID
FROM JSONBTABLE
WHERE JSONB_COL = %s
""", (Json(jsonb_dict),)
)
# This returns nothing. No match. Nada
cur.fetchone()
如果我现在在Python中将JSONB插入表中,然后按上述方式查询,cur.fetchone()
将返回2
的id,与python代码中插入的副本的OCRB_ID相匹配。插入示例如下:
cur.execute(
"""
INSERT INTO JSONBTABLE(JSONB_COL)
VALUES(%s)
""", (Json(jsonb_dict),)
)
conn.commit()
在视觉上查看表的结果,在python代码中插入完全重复后,SELECT JSONB_COL FROM JSONBTABLE
它们是相同的。
但Postgres发现它们不相同,因为以下内容返回FALSE
SELECT
(SELECT JSONB_COL FROM JSONBTABLE where JSONB_ID = 1) =
(SELECT JSONB_COL FROM JSONBTABLE where JSONB_ID = 2);
更奇怪的是,这会返回TRUE
:
SELECT
(SELECT JSONB_COL->'field1' FROM JSONBTABLE where JSONB_ID = 1) =
(SELECT JSONB_COL->'field1' FROM JSONBTABLE where JSONB_ID = 2);
但这会返回FALSE
:
SELECT
(SELECT JSONB_COL->'field2' FROM JSONBTABLE where JSONB_ID = 1) =
(SELECT JSONB_COL->'field2' FROM JSONBTABLE where JSONB_ID = 2);
同样,在视觉上,JSONB_ID = 1
和JSONB_ID = 2
的整个JSONB记录的所有字段都是相同的。我在视觉上检查了他们,性格特征。