Создайте запрос обновления MySQL на Python, который заключает в кавычки только строки, а не числа

#python #mysql #mysql-connector #mysql-connector-python

#python #mysql #mysql-connector #mysql-connector-python

Вопрос:

Я хотел бы создать запрос на обновление из списка ключей и значений, заключая значения в кавычки только там, где это необходимо. Прямо сейчас (с приведенным ниже кодом) кавычки появляются как вокруг строк, так и вокруг целых чисел. Как я могу сделать это эффективно?

 attributes = ['filename','filesize']
media_id = 12345
sqlbase = """UPDATE media
             SET %s
             WHERE media_id = %s"""
setpieces = []
values = []

setpieces.append("""timestamp_modified = %s""" % (time.time()))

#Recurse through all attributes in the class
for key in attributes:
  #For each key, get the value
  if key in attributes:
    value = getattr(self, key, None)
    setpieces.append("""%s = '%s'""" % (key, value))

query = sqlbase % (', '.join(setpieces), media_id)
  

Ответ №1:

Давайте MySQLdb решим это, передав параметры запроса в execute() :

 sqlbase = """UPDATE media
             SET {query}
             WHERE media_id = %(media_id)s"""

mapping = {key: getattr(self, key, None) for key in ['filename', 'filesize']}
mapping['media_id'] = 12345
setpieces = ["{key} = %({key})s".format(key=key) for key in mapping]   
            ["timestamp_modified = %s" % time.time()]

cursor.execute(sqlbase.format(query=','.join(setpieces)), mapping)
  

В качестве бонуса вы получаете экранирование, которое поможет предотвратить SQL-инъекции.

Кроме того, просто примечание. Как вы видите, создание такого запроса вручную выглядит не очень читабельным и действительно хрупким. Именно здесь переключение на ORM может уменьшить количество головных болей и сюрпризов, взгляните, например: Pony ORM , или sqlalchemy .

Комментарии:

1. Спасибо. я использую mysql.connector вместо mysqldb для объединения в пул соединений. есть ли способ выполнить такой параметризованный запрос с помощью mysql.connector?

2. @ensnare ой, видел mysql-python и решил, что это так MySQLdb . Хотя синтаксис должен быть таким же .

3. не беспокойтесь. у mysql connector проблемы с параметризацией запросов с помощью dicts. как я могу сам параметризовать это и передать один окончательный запрос в mysql?

4. @ensnare хм, какие проблемы? Должно работать, согласно документам.. весь смысл ответа состоит в том, чтобы сделать это с помощью самого клиента mysql python, поскольку он «знает», нужно ли ему заключать в кавычки или нет, в зависимости от типа данных..

5. mysqlconnector не может параметризовать сопоставления