Python处理Google API JSON嵌套引号写入PostgreSQL报错求助
解决Google API JSON嵌套引号存入PostgreSQL JSON列的问题
兄弟,这问题我太懂了!之前对接Google Places API存PostgreSQL JSON列时,也踩过一模一样的坑——手动转义引号简直是噩梦,还容易踩SQL注入的坑。咱们先拆解下你代码里的问题,再给你最优解决方案:
问题出在哪?
你现在的写法是直接拼接SQL字符串,这会导致三个致命问题:
- 引号冲突:你把JSON字符串用单引号
'%s'包裹,但JSON本身可能包含单引号(比如商家名称里的O'Neil),手动转义根本顾不过来,PostgreSQL解析时直接语法报错。 - 双引号误用:SQL里字符串值要用单引号,你写的
where google_place_id="%s"会让PostgreSQL把"%s"当成列名,而不是字符串值,这也是报错的潜在原因。 - SQL注入风险:如果
rows[0]是恶意构造的字符串,直接拼接会导致数据库被攻击。
最优解决方案:用参数化查询
PostgreSQL的Python驱动(比如psycopg2)原生支持参数化查询,完全不用你手动处理引号转义,还能自动适配JSON类型。直接看修改后的代码:
import urllib.request import json import psycopg2 # 假设你已经通过psycopg2建立了数据库连接conn cursor = conn.cursor() # 用f-string拼接API URL更清晰(注意替换成你的真实API Key) place_id = str(rows[0]) url = f'https://maps.googleapis.com/maps/api/place/details/json?placeid={place_id}&key=YourActualAPIKey' # 建议用with语句管理网络请求,自动关闭连接 with urllib.request.urlopen(url) as response: response_data = response.read() # 解析成Python字典(psycopg2可以直接把字典转成PostgreSQL的JSON类型) place_details = json.loads(response_data) # 关键:用参数化查询,占位符%s不用加引号! update_query = ''' UPDATE public.attraction SET g_json_1 = %s WHERE google_place_id = %s ''' # 把Python字典和place_id作为参数传给execute,驱动会自动处理类型和引号 cursor.execute(update_query, (place_details, place_id)) # 别忘了提交事务,不然修改不会生效 conn.commit() # 最后关闭游标和连接(如果不再用的话) cursor.close() conn.close()
为什么这能解决问题?
- 自动处理引号:参数化查询会把你的JSON数据(不管是Python字典还是JSON字符串)当成一个整体参数,PostgreSQL会正确识别其JSON类型,完全不用你手动转义任何引号。
- 避免SQL注入:参数化查询会把用户输入(比如place_id)当成纯数据,而不是SQL语句的一部分,彻底杜绝注入风险。
- 类型适配:psycopg2会自动把Python的
dict转换成PostgreSQL的JSON类型,比你手动json.dumps再存更省心。
额外小提示
- 如果你的PostgreSQL列类型是
JSONB(比JSON更适合查询),这个代码同样适用,psycopg2会自动适配。 - 永远不要手动拼接包含用户输入或外部数据的SQL语句,参数化是行业标准的最佳实践。
内容的提问来源于stack exchange,提问作者Nishant Sah
相关产品推荐
相关产品推荐

