什么是sqlite3.OperationalError:near" t":语法错误意味着什么

时间:2018-06-02 19:38:58

标签: python sqlite

我正在使用python并尝试使用

更新行
db=sqlite3.connect('db')
cursor=db.execute('select * from infos where is_processed=0')
films=cursor.fetchall()
cursor.close()
db.close()
for film in films:
    inputLayer=np.array([film[1],film[2],film[3]],dtype=float)
    name=film[0]
    #print inputLayer
    NeuralNetwork3.nn(inputLayer,film[4])
    sql="update infos set is_processed=1 where file_name='"+name+"'"
    db = sqlite3.connect('db')
    db.execute(sql)
    db.commit()
    db.close()

我得到:sqlite3.OperationalError:near" t":语法错误有什么问题? 注意它指向第34行; db.excute(sql)"并说在那一行是错误

1 个答案:

答案 0 :(得分:2)

假设name包含单引号,后跟t,如

name = "don't look now"
sql = "update foo set is_processed=1 where bar='"+name+"'"

然后sql等于

In [156]: sql
Out[156]: "update foo set is_processed=1 where bar='don't look now'"

和sqlite3会认为条件为where bar='don',后跟语法错误t look now'sqlite3然后提出

sqlite3.OperationalError: near "t": syntax error

这是为什么你应该always use parametrized SQL的一个例子。要避免此问题(并保护您的代码免受SQL注入攻击),请使用参数化SQL并将值的序列(或,取决于paramstyle,映射)作为cursor.execute的第二个参数传递:

sql = "update foo set is_processed=1 where bar=?"
cursor.execute(sql, [name])

当你传递参数(例如[name])作为第二个参数时 cursor.execute,sqlite3将为您提供单引号。

根据Python Database API,当您将parameters作为第二个参数传递给cursor.execute时(我的重点):

  

模块将使用参数对象的__getitem__方法进行映射     位置(整数)或名称(字符串)到参数值。这个     允许将序列和映射用作输入。

     

术语绑定是指将输入值绑定到数据库的过程     执行缓冲区。 实际上,这意味着输入值是     直接用作操作中的值。不应要求客户     到"逃避"该值可以使用 - 该值应该等于     实际的数据库值

这是一个可运行的玩具示例,可帮助您查看问题以及如何使用参数化SQL来避免问题:

import sqlite3

with sqlite3.connect(':memory:') as conn:
    cursor = conn.cursor()
    cursor.execute('''CREATE TABLE foo
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  bar TEXT,
                  is_processed BOOL)''')
    name = "don't look now"

    sql = "update foo set is_processed=1 where bar='"+name+"'"
    print(sql)
    cursor.execute(sql)

    # comment out `cursor.execute(sql)` above and compare with
    # sql = "update foo set is_processed=1 where bar=?"
    # cursor.execute(sql, [name])