You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何处理含单/双引号的字符串用于SQL查询?

Python构造SQL INSERT查询的引号冲突与标准解决方案

问题场景

用f-string直接拼接SQL INSERT语句时,遇到含特殊引号的字符串会触发MariaDB语法错误:

  • 字段值含双引号(如Someword "somename")时,双引号拼接方式会导致SQL语句引号嵌套冲突
  • 切换为单引号拼接后,若字段值含单引号(如Château La Chouette d'Or),又会出现单引号截断SQL语句的问题

错误示例代码

第一种双引号拼接写法

query_ = f'INSERT INTO {entity} (id, link, name, country_id) SELECT  {key}, "{value}", "{row[0]}", id FROM countries WHERE name = "{row[1]}";'

拼接后触发错误的SQL语句:

INSERT INTO wineries (id, link, name, country_id) SELECT  30052, "someword-somename", "Someword "somename"", id FROM countries WHERE name = "France";

第二种单引号拼接写法

query_ = f"INSERT INTO {entity} (id, link, name, country_id) SELECT  {key}, '{value}', '{row[0]}', id FROM countries WHERE name = '{row[1]}';"

当row[0]为Château La Chouette d'Or时,单引号会截断SQL语句,触发语法错误。

标准优雅解决方案:使用参数化查询

直接拼接字符串不仅会导致引号冲突,还存在SQL注入风险,**参数化查询(Prepared Statements)**是Python操作数据库的标准解决方案,由数据库驱动自动处理特殊字符转义。

实现步骤(以MariaDB驱动为例)

  1. 安全处理表名:表名不能用参数化占位符,需确保entity是可信值(如预定义的常量列表),避免SQL注入

    # 预定义允许的表名,确保entity来源安全
    allowed_tables = ['wineries', 'countries']
    if entity not in allowed_tables:
        raise ValueError("非法的表名")
    
  2. 构造带占位符的SQL语句:用%s作为值的占位符(MariaDB驱动标准占位符)

    query_ = f'INSERT INTO {entity} (id, link, name, country_id) SELECT %s, %s, %s, id FROM countries WHERE name = %s;'
    
  3. 传入参数执行查询:将变量以元组形式传入execute()方法,驱动自动处理转义

    # 假设conn是已建立的MariaDB连接
    cursor = conn.cursor()
    # 参数顺序与占位符一一对应:key, value, row[0], row[1]
    cursor.execute(query_, (key, value, row[0], row[1]))
    conn.commit()
    

优势

  • 彻底解决引号、特殊字符导致的语法错误
  • 从根源避免SQL注入风险,符合工业级代码规范
  • 代码更简洁易维护,无需手动处理字符串转义

内容的提问来源于stack exchange,提问作者Andrey Starkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 04:45:29