含单引号的JSON数据插入CrateDB失败的解决方法咨询
解决CrateDB插入含单引号的OBJECT类型字段问题
这个问题的核心是SQL字符串的转义规则和JSON的转义规则搞混了——你用单引号把整个JSON包裹成SQL字符串,但SQL里要转义单引号的话,得用两个连续的单引号,而不是JSON里的反斜杠。
方案一:手动修正SQL语句的单引号转义
把你数据里的Bart\'s改成Bart''s,也就是把单个单引号替换成两个,这样CrateDB就能正确解析这个SQL字符串了。修改后的插入语句如下:
INSERT into users (userdata) VALUES ('{"area_code": "2", "companyname": "TEC", "cos": "National24Hrs-Standard", "country_code": "AUS", "cucm_dn": "26902", "ddi": "84236902", "department": null, "device_type": "Cisco 8945 SIP", "divisionname": "Demonstrations", "emailaddress": "bart.simpson@core.demo.telstra.com", "extension": "26902", "extra1": null, "extra2": null, "extra3": null, "extra4": null, "featuregroup": "Mobile Worker", "firstname": "Bart", "information": null, "ippbxchosen": "TEC-CL-1", "language": "English - United States", "lastname": "Simpson", "locationname": "Sydney", "mask": "61284236902", "pickupgroup": null, "postcode": "2000", "presence": "Y", "role": "enduser", "security_profile": "EndUser-SP1", "snr": "Bart''s Mobile:0457503561,Bart Simpson:457503561", "username": "bart.simpson@core.demo.telstra.com", "voicemail": "UCX-Advanced-CoS"}')
方案二:用Python参数化查询(推荐)
手动转义不仅麻烦,还容易出错,更安全可靠的方式是用Python的参数化查询,让数据库驱动自动处理转义逻辑,还能避免SQL注入风险。
如果你用的是官方的crate Python客户端,代码示例如下:
from crate import client # 连接CrateDB conn = client.connect("http://your-cratedb-host:4200") cursor = conn.cursor() # 准备要插入的JSON数据(直接用Python字典即可,不用转成字符串) user_data = { "area_code": "2", "companyname": "TEC", "cos": "National24Hrs-Standard", "country_code": "AUS", "cucm_dn": "26902", "ddi": "84236902", "department": None, "device_type": "Cisco 8945 SIP", "divisionname": "Demonstrations", "emailaddress": "bart.simpson@core.demo.telstra.com", "extension": "26902", "extra1": None, "extra2": None, "extra3": None, "extra4": None, "featuregroup": "Mobile Worker", "firstname": "Bart", "information": None, "ippbxchosen": "TEC-CL-1", "language": "English - United States", "lastname": "Simpson", "locationname": "Sydney", "mask": "61284236902", "pickupgroup": None, "postcode": "2000", "presence": "Y", "role": "enduser", "security_profile": "EndUser-SP1", "snr": "Bart's Mobile:0457503561,Bart Simpson:457503561", "username": "bart.simpson@core.demo.telstra.com", "voicemail": "UCX-Advanced-CoS" } # 参数化插入 cursor.execute("INSERT INTO users (userdata) VALUES (?)", (user_data,)) conn.commit() # 关闭连接 cursor.close() conn.close()
如果用的是psycopg2之类适配PostgreSQL的驱动,写法类似,把占位符改成%s即可:
import psycopg2 conn = psycopg2.connect("dbname=your_db user=your_user host=your-cratedb-host port=5432") cursor = conn.cursor() # 直接传入Python字典即可,驱动会自动处理转义 cursor.execute("INSERT INTO users (userdata) VALUES (%s)", (user_data,)) conn.commit() cursor.close() conn.close()
为什么之前用反斜杠没用?因为反斜杠是JSON的转义符,但你的JSON是被包裹在SQL的单引号字符串里的,CrateDB解析SQL的时候,会优先遵循SQL的规则——SQL里单引号字符串的转义符是另一个单引号,反斜杠在这里会被当作普通字符处理,所以原来的Bart\'s会被SQL解析成Bart\s,同时提前结束字符串,导致语法错误。
内容的提问来源于stack exchange,提问作者Glen Stokes
相关产品推荐
相关产品推荐

