Вы получаете эту ошибку, потому что вы пытались выполнить
UPDATE tblGames SET genre=Adventure WHERE game = 'Shadow of the Colossus';
, в то время как вы, вероятно, намеревались выполнить
UPDATE tblGames SET genre='Adventure' WHERE game = 'Shadow of the Colossus';
Если вы просто сделаете это изменение, оно будет работать, но я буду не согласен с вами, потому что ваш код опасен .
В вашем коде есть большая проблема, на которую уже указали комментарии.Вы объединяете ваш запрос, используя неанализованные строки, которые являются антипаттернами.Библиотека sqlite3 Python позволяет вам связывать параметры с вашими запросами.Любой ?
в вашем запросе будет заменен значением по вашему выбору (пример ниже).
Однако у вас есть другая проблема.Вы не можете связать имя столбца как параметр.Попытка сделать это будет иметь 'columnName'
в запросе вместо columnName
.Там нет безопасного способа сделать это, потому что это еще один антипаттерн.Но так как мы здесь, давайте по крайней мере сделаем это безопасным способом.Нам придется встраивать имя столбца в запрос, но мы не можем встроить какой-либо пользовательский ввод, опасаясь внедрения SQL.Поэтому мы должны убедиться, что встраиваемая строка является именем столбца и только именем столбца.Другими словами, нам нужно будет санировать входные данные.
Приведенный ниже код будет санировать имя столбца, так что в запрос попадут только действительные имена столбцов.Он также встраивает другие параметры, используя функциональность sqlite3, которая очищает входные данные для вас.
def amendRec():
edit = "yes"
while edit != 'exit':
keyfield = input("enter the game name of the record you want to edit. ")
field = input("enter the field you want to change. ")
# Check whether the specified colmun exists or not.
# Any SQL injection will fail this test.
query = "PRAGMA table_info ('tblGames');"
columnExists = False
for columnName in map(lambda x: x[1], cur.execute(query)):
if columnName == field:
columnExists = True
if columnExists:
# field can only be one of the column names since it's sanitized above.
query = "UPDATE tblGames SET {} = ? WHERE game = ? ;".format(field)
new_val = input("enter the new data for this field. ")
# We pass in a tuple containing our desired parameters as the second parameter of cursor.execute.
# new_val will replace the first ? and keyfield will replace the second ?.
cursor.execute(query, (new_val, keyfield))
conn.commit()
print("\nRecord Updated\n")
else:
print("Sorry, that column doesn't exist.")
edit = input("type 'exit' to stop editing, or press enter to continue. \n")
showtable()
В идеале вы должны иметь field
для ввода с множественным выбором, а не для ввода текста.Таким образом, вы можете быть более уверены, что это безопасно, и вам придется сделать на один запрос меньше к базе данных.