如何插入包含' /'的值进入sqlite?

时间:2018-01-18 11:48:55

标签: python python-3.x

conn = sqlite3.connect(self.__database_name)
c = conn.cursor()
sql = 'INSERT OR IGNORE INTO ' + self.__article_url_table_name + ' (url) values (%s)' % (href)
c.execute(sql)
conn.commit()

我在调用的行中收到以下错误:c.execute(sql)

  

sqlite3.OperationalError:near" /":语法错误

url变量是一个字符串,其中包含一个类似于:https://www.foo.com/bar.html

的网址

我的代码中有什么错误?

2 个答案:

答案 0 :(得分:5)

您不应该使用字符串插值来编写SQL查询。除了你遇到的问题之外,它让你对SQL注入开放。改为使用参数:

DayOfWeek

答案 1 :(得分:5)

错误是您没有以正确的方式使用db-api。您正在使用字符串格式构建SQL查询:

sql = "INSERT OR IGNORE INTO some_table (url) values (%s)" % href

这导致两个问题。

第一个是正确处理引用和转义。在您的情况下,您可以通过在格式符号周围添加引号来解决,例如:

sql = "INSERT OR IGNORE INTO some_table (url) values ('%s')" % href

但如果href包含引号,这仍然会中断。

第二个也是更重要的问题是your code is now opened to sql injection attacks

正确使用db-api将解决这两个问题:只需在sql字符串中使用dp-api模块的占位符(对于sqlite,它是'?'),并将参数传递给cursor.execute()调用。然后你的db-api模块将负责正确的引用/转义并正确清理你的参数以防止sql注入:

sql = "INSERT OR IGNORE INTO some_table (url) values (?)"
c.execute(sql, (href,))

请注意,这不适用于表名,仅适用于传递给select,insert或delete查询的值,因此在您的情况下,您仍然必须对表名使用字符串格式:

sql = "INSERT OR IGNORE INTO {} (url) values (?)".format(self.__article_url_table_name)
c.execute(sql, (href,))

完全不相关的我注意到你对类属性使用__private命名约定。此约定触发名称修改机制,主要用于防止意外覆盖某些属性。实际上,这几乎从来不需要(最终对于框架中的基类的某些实现细节,甚至那时)并且可能真的很烦人。 “实现属性”的约定是使用单个前导下划线,所有python程序员都将其理解为“实现细节,不要弄乱这个或者你自己”。