在Python和sqlite中转义字符
我有一个Python脚本,它可以把原始的电影文本文件读入一个sqlite数据库。
我使用re.escape(title)这个方法来给字符串加上转义字符,这样在执行插入操作之前就能确保它们在数据库中是安全的。
但是,为什么下面这个不管用呢:
In [16]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='\'Allo\ \'Allo\!\"\ \(1982\)'")
--------------------------------------------------------------------------- OperationalError Traceback (most recent call last)
/home/rajat/Dropbox/amdb/<ipython console> in <module>()
OperationalError: near "Allo": syntax error
而这个就可以用(在两个地方去掉了\'):
In [17]: c.execute("UPDATE movies SET rating = '8.7' WHERE name='Allo\ Allo\!\"\ \(1982\)'") Out[17]: <sqlite3.Cursor object at 0x9666e90>
我搞不明白为什么会这样。我也不能去掉那些开头的引号,因为它们实际上是电影标题的一部分。
谢谢。
4 个回答
10
SQLite不支持反斜杠转义序列。在字符串中,如果想表示单引号,就需要把它写成两个单引号:'''Allo ''Allo! (1982)'
。
不过,就像Donal说的,你应该使用参数。
15
我用 re.escape(title) 来给字符串添加转义字符,这样可以让它们在数据库中安全使用。
需要注意的是,re.escape
只是让字符串在正则表达式中安全使用,并不是为了让它在数据库中安全。正如 @Donal 所说,你需要的是 Python 数据库 API 中的 参数替换 概念——这才是真正让字符串在数据库中安全的方法。
133
你这样做是不对的,真的。你应该使用参数,像这样:
c.execute("UPDATE movies SET rating = ? WHERE name = ?", (8.7, "'Allo 'Allo! (1982)"))
这样一来,你就完全不需要进行任何的引号处理了,而且如果这些值是来自不可信的地方,你在这里就能100%安全,避免SQL注入攻击。