Подтвердить что ты не робот

Поддерживает ли Python MySQL подготовленные заявления?

Раньше я работал над PHP-проектом, когда подготовленные операторы делали запросы SELECT на 20% быстрее.

Мне интересно, работает ли он на Python? Кажется, я не могу найти ничего, что конкретно говорит, что это делает или НЕ.

4b9b3361

Ответ 1

Прямой ответ, нет.

joshperry answer является хорошим объяснением того, что он делает.

Из eugene y ответьте на аналогичный вопрос,

Проверьте MySQLdb Комментарии к пакетам:

"Параметризация" выполняется в MySQLdb путем экранирования строк и затем слепо интерполировать их в запрос, вместо использования   MYSQL_STMT API. В результате строки unicode должны проходить через два   промежуточные представления (закодированная строка, экранированная строка)   прежде чем они будут получены базой данных.

Итак, ответ: Нет, это не так.

Ответ 2

Большинство языков предоставляют способ создания общих параметризованных операторов, Python ничем не отличается. Когда параметризованный запрос используется, базы данных, которые поддерживают подготовку операторов, автоматически сделают это.

В python параметризованный запрос выглядит так:

cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])

Конкретный стиль параметризации может отличаться в зависимости от вашего драйвера, вы можете импортировать свой модуль db, а затем сделать print yourmodule.paramstyle.

От PEP-249:

paramstyle

       String constant stating the type of parameter marker
       formatting expected by the interface. Possible values are
       [2]:

           'qmark'         Question mark style, 
                           e.g. '...WHERE name=?'
           'numeric'       Numeric, positional style, 
                           e.g. '...WHERE name=:1'
           'named'         Named style, 
                           e.g. '...WHERE name=:name'
           'format'        ANSI C printf format codes, 
                           e.g. '...WHERE name=%s'
           'pyformat'      Python extended format codes, 
                           e.g. '...WHERE name=%(name)s'

Ответ 3

После быстрого просмотра метода execute() объекта Cursor пакета MySQLdb (вроде бы де-факто пакет для интеграции с mysql, я думаю), кажется, что (по крайней мере по умолчанию) это только строковая интерполяция и цитирование, а не фактический параметризованный запрос:

if args is not None:
    query = query % db.literal(args)

Если это не строковая интерполяция, то что такое?

В случае выполнения он фактически пытается выполнить вставку/замену как один оператор, а не выполнять его в цикле. Что-то об этом, кажется, нет волшебства. По крайней мере, не по умолчанию.

EDIT: О, я только что понял, что оператор modulo можно переоценить, но я почувствовал себя обманом и смазал источник. Однако не найдено переопределения mod.

Ответ 4

Использование интерфейса SQL, предложенное Amit, может работать, если вас беспокоит только производительность. Тем не менее, вы теряете защиту от SQL-инъекции, которую может принести встроенная поддержка Python для подготовленных операторов. Python 3 имеет модули, которые обеспечивают подготовленную поддержку операторов PostgreSQL. Для MySQL "oursql", похоже, обеспечивает истинную поддержку подготовленных операторов (не подделка, как в других модулях).

Ответ 6

Не связанный напрямую, но этот ответ на другой вопрос в SO включает в себя подробности синтаксиса "templated" запросов. Я бы сказал, что автоматическое экранирование будет их самой важной функцией...

Что касается производительности, обратите внимание на метод executemany на объекты курсора. Он объединяет несколько запросов и выполняет их все за один раз, что приводит к повышению производительности.

Ответ 7

Существует решение!

Вы можете использовать их, если поместить их в хранимую процедуру на сервере и вызвать их как это из python...

cursor.callproc(Procedurename, args)

Вот небольшой учебник по хранимым процедурам в mysql и python.

http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/