在数据库查询字符串中转义引号的好方法?
Posted
技术标签:
【中文标题】在数据库查询字符串中转义引号的好方法?【英文标题】:A good way to escape quotes in a database query string? 【发布时间】:2010-10-28 04:13:30 【问题描述】:我尝试了各种 Python 模块,但它们要么逃逸太多,要么逃逸方式错误。 您发现在 Python 中转义引号 (", ') 的最佳方法是什么?
【问题讨论】:
你想在什么情况下转义?对于python字符串,还是入数据库? 它是 Postgres 数据库查询的一部分。 【参考方案1】:如果它是数据库查询的一部分,您应该可以使用Parameterized SQL Statement。
除了转义引号外,这还将处理所有特殊字符并保护您免受SQL injection attacks 的侵害。
【讨论】:
+1:如果您在数据库查询中转义引号,则说明您执行的 SQL 错误。 太好了,现在我只需要一份 Python 3.0。 为什么需要 Python 3.0 才能使用参数化 SQL 语句?它们存在于所有版本和所有 Postgres Python 接口中。 @S.Lott 你能解释一下为什么吗?您是否有比转义引号更好/更清洁的方法的链接? 并非所有内容都可以参数化。特别是如果您尝试动态构建 SQL 查询。像动态表名或动态运算符一样,根据布尔值使用>
或 <
。或者有不同数量的参数。【参考方案2】:
使用json.dumps
。
>>> import json
>>> print json.dumps('a"bc')
"a\"bc"
【讨论】:
当字符串中包含 Unicode 字符时失败:print json.dumps(u"£")
prints "\u00a3"
除了上面的问题之外,这工作得很好,但是对于可以更简单地解决的问题,这是一个非常繁重的解决方案。【参考方案3】:
转义字符串并将其他对象转换为编程形式的简单标准方法是使用内置的repr()
函数。它将对象转换为您需要使用手动代码输入的表示形式。
例如:
s = "I'm happy I am \"here\" now"
print repr(s)
>> 'I\'m happy I am "here" now'
没有什么奇怪的技巧,它是内置的,它只适用于大多数用途。
【讨论】:
这可能不是 OP 想要的。 repr 确实转义了引号,但它也将字符串包裹在单引号中。例如:repr("King's Castle") 变成 '"King\'s Castle"'(注意引号)。 我最终得到u'I\'m happy I am "here" now'
。
repr
使用 Python 规则转义,带有反斜杠。我的印象是 OP 想要返回一个具有不同规则的 SQL 文字——单引号应该加倍,反斜杠不重要。【参考方案4】:
三重单引号将方便地封装SQL查询中经常使用的单引号:
c.execute('''SELECT sval FROM sdat WHERE instime > NOW() - INTERVAL '1 days' ORDER BY instime ASC''')
【讨论】:
【参考方案5】:如果使用 psycopg2,其execute()
方法具有内置转义:
cursor.execute("SELECT column FROM table WHERE column=%s AND column2=%s", (value1, value2))
请注意,您为执行方法(字符串和元组)提供了两个参数,而不是使用 Python 的 % 运算符来修改字符串。
从这里窃取的答案:psycopg2 equivalent of mysqldb.escape_string?
【讨论】:
【参考方案6】:如果您使用的 psycopg2 具有转义字符串的方法:psycopg2.extensions.adapt()
请参阅 How to quote a string value explicitly (Python DB API/Psycopg2) 以获得完整答案
【讨论】:
【参考方案7】:三双引号最适合转义:
string = """这将跨越'单引号','双引号', 和文字 EOL 都在同一个字符串中。"""
【讨论】:
在这种情况下不起作用:string = """This is a string "containing a quote""""
【参考方案8】:
为了解决更一般的问题,我有一个程序,我需要在一个平面文件中存储任何组字符,制表符分隔。显然,在“集合”中有标签会导致问题。
我使用了 output_f.write(repr(str)) 而不是 output_f.write(str),这解决了我的问题。 阅读速度较慢,因为我在阅读时需要 eval() 输入,但总的来说,它使代码更清晰,因为我不再需要检查边缘情况。
【讨论】:
repr/eval 在这种情况下是个坏主意。您可以改用csv
模块。它将为您处理在字段中嵌入标签【参考方案9】:
对于我的用例,我在数据库中保存了一个段落,在该段落的某个地方可能有一些带有单引号的文本 (example: Charlie's apple sauce was soggy)
我发现这个效果最好:
database_cursor.execute('''INSERT INTO books.collection (book_name, book_quoted_text) VALUES ('%s', "%s")''' % (book_name, page_text.strip()))
您会注意到,在将 INSERT 语句包装在 '''
中之后,我使用了 ""
【讨论】:
以上是关于在数据库查询字符串中转义引号的好方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 PHP 的 mysqli_query() 中转义双引号字符?
NamedParameterJdbcTemplate Oracle SQL,如何在命名查询中转义单引号?