Python MySQL Параметризованные Запросы



Мне трудно использовать модуль MySQLdb для вставки информации в мою базу данных. Мне нужно вставить 6 переменных в таблице.



cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)

""")


кто-нибудь может помочь мне с синтаксисом?

590   7  

7 ответов:

остерегайтесь использования Строковой интерполяции для SQL-запросов, так как она не будет правильно экранировать входные параметры и оставит ваше приложение открытым для уязвимостей SQL-инъекции. разница может показаться тривиальной, но на самом деле она огромна.

неверно (с проблемами безопасности)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))

правильно (с побегом)

c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))

это добавляет путаницы, что модификаторы, используемые для привязки параметров в инструкции SQL различается различные реализации API БД и что клиентская библиотека mysql использует printf синтаксис стиля вместо более общепринятого '?'маркер (используется например. python-sqlite).

у вас есть несколько вариантов. Вы захотите освоиться с итерацией строк python. Которые вы могли бы иметь больше успеха в будущем, когда вы хотите знать такие вещи.

лучше для запросов:

some_dictionary_with_the_data = {
    'name': 'awesome song',
    'artist': 'some band',
    etc...
}
cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)

        """, some_dictionary_with_the_data)

учитывая, что у вас, вероятно, уже есть все ваши данные в объекте или словаре, второй формат подойдет вам лучше. Также это отстой, чтобы считать" %s " появления в строке, когда вы должны вернуться и обновить этот метод через год:)

связанные документы дают следующий пример:

   cursor.execute ("""
         UPDATE animal SET name = %s
         WHERE name = %s
       """, ("snake", "turtle"))
   print "Number of rows updated: %d" % cursor.rowcount

Так что вам просто нужно адаптировать это к вашему собственному коду-пример:

cursor.execute ("""
            INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
            VALUES
                (%s, %s, %s, %s, %s, %s)

        """, (var1, var2, var3, var4, var5, var6))

(Если SongLength является числовым, вам может потребоваться использовать %d вместо %s).

на самом деле, даже если ваша переменная (SongLength) является числовой, вам все равно придется отформатировать ее с помощью %s, Чтобы правильно привязать параметр. Если вы попытаетесь использовать %D, вы получите сообщение об ошибке. Вот небольшой отрывок из этой ссылки http://mysql-python.sourceforge.net/MySQLdb.html:

чтобы выполнить запрос, вам сначала нужен курсор, а затем вы можете выполнять запросы на нем:

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

в этом примере max_price=5 зачем тогда использовать %s в строке? Потому что MySQLdb преобразует его в литеральное значение SQL, которое является строкой '5'. Когда он будет закончен, запрос фактически скажет:"...Где цена

в качестве альтернативы выбранному ответу и с той же безопасной семантикой Марселя, вот компактный способ использования словаря Python для указания значений. Он имеет то преимущество, что его легко изменить при добавлении или удалении столбцов для вставки:

  meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
  insert='insert into Songs ({0}) values ({1})'.
        .format(','.join(meta_cols), ','.join( ['%s']*len(meta_cols) ))
  args = [ meta[i] for i in meta_cols ]
  cursor=db.cursor()
  cursor.execute(insert,args)
  db.commit()

здесь мета это словарь, содержащий значения для вставки. Обновление может быть сделано таким же образом:

  meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
  update='update Songs set {0} where id=%s'.
        .format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
  args = [ meta[i] for i in meta_cols ]
  args.append( songid )
  cursor=db.cursor()
  cursor.execute(update,args)
  db.commit()

вот еще один способ сделать это. Это задокументировано на официальном сайте MySQL. https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html

в духе, он использует тот же механик ответа @Trey Stout. Тем не менее, я нахожу это более красивым и более читаемым.

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

и чтобы лучше проиллюстрировать любую потребность в переменных:

NB: обратите внимание, что побег выполняется.

employee_id = 2
first_name = "Jane"
last_name = "Doe"

insert_stmt = (
  "INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
  "VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)

первое решение работает хорошо. Я хочу добавить здесь одну маленькую деталь. Убедитесь, что переменная, которую вы пытаетесь заменить / обновить, должна быть типом str. Мой тип mysql является десятичным, но мне пришлось сделать переменную параметра как str, чтобы иметь возможность выполнить запрос.

temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)

Comments

    Ничего не найдено.