编写JSON保留双反斜杠

时间:2019-12-03 00:48:07

标签: json python-3.x psycopg2

我想将python数据结构作为json存储在Postgresql数据库上。

json.dumps()运作良好,并且我得到了格式正确的JSON,如下所示:

>>> import json
>>> j = { 'table': '"public"."client"' }
>>> json.dumps(j)
'{"table": "\\"public\\".\\"client\\""}'

如果我执行print(json.dumps(j)),则仅打印一个反斜杠,因为Python将其用作转义字符,如:

>>> import json
>>> j = { 'table': '"public"."client"' }
>>> json.dumps(j)
'{"table": "\\"public\\".\\"client\\""}'
>>> print(json.dumps(j))
{"table": "\"public\".\"client\""}

问题

我认为,当我尝试使用psycopg2backslashes should not be stripped将这个json存储在Postgresql上时。

import psycopg2
import json

try:
    conn = psycopg2.connect("service=geotuga")
    cursor = conn.cursor()
    j = { 'table': '"public"."client"' }
    cursor.execute("INSERT INTO users.logger(subject,detail) VALUES (%s, %s);", ('json',json.dumps(j) ))
    conn.commit()
    cursor.close()
except (Exception, psycopg2.Error) as e:
    print(e)
finally:
    if conn is not None:
        conn.close()

在数据库上,json字符串存储为:{"table": "\"public\".\"client\""}。双反斜杠不见了。

如何存储由json.dumpspsycopg2正确创建的JSON,而又不会丢失双反斜杠?

注意:存储在数据库中的json不再有效。例如,如果我尝试用Javascript解析它,则会失败:

> x = '{"table": "\"public\".\"client\""}'
'{"table": ""public"."client""}'
> JSON.parse(x)
SyntaxError: Unexpected token p in JSON at position 12

1 个答案:

答案 0 :(得分:0)

正如 luigibertaco 所指出的那样,问题是我如何观察数据库中的数据。 已使用psycopg2 将双反斜杠正确写入数据库。

如果我这样做:

# select detail from users.logger where subject = 'json' limit 1;
               detail               
------------------------------------
 {"table": "\"public\".\"client\""}
(1 row)

输出仅显示一个斜杠。

但是,如果我使用quote_literal Postgresql函数,则会得到原始数据:

# select quote_literal(detail) from users.logger  where subject = 'json' limit 1;
               quote_literal               
-------------------------------------------
 E'{"table": "\\"public\\".\\"client\\""}'
(1 row)

Postgresql能够解析字符串

我所做的另一项检查是在Postgresql端测试json解析。它可以正常工作,因此字符串已正确编码。

# select detail::json->'table' from users.logger where subject = 'json' limit 1;
        ?column?         
-------------------------
 "\"public\".\"client\""
(1 row)