что означает sqlite3.OperationalError: вблизи "t": синтаксическая ошибка означает - PullRequest
0 голосов
/ 02 июня 2018

Я использую 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: вблизи "t": ошибка синтаксиса, что не так?Обратите внимание, что он указывает на строку «db.excute (sql)» и говорит, что в этой строке ошибка

1 Ответ

0 голосов
/ 02 июня 2018

Предположим, 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

Это пример того, почему вы должны всегда использовать параметризованный SQL .Чтобы избежать этой проблемы (и защитить ваш код от атак с использованием SQL-инъекций), используйте параметризованный SQL и передайте последовательность (или, в зависимости от параметра стиля, сопоставление) значений в качестве второго аргумента cursor.execute:

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

Когда вы передаете аргументы (например, [name]) в качестве второго аргумента cursor.execute, sqlite3 будет экранировать одинарную кавычку для вас.


В соответствии с API базы данных Python , когда вы передаете 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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...