Раньше я работал над PHP-проектом, когда подготовленные операторы делали запросы SELECT на 20% быстрее.
Мне интересно, работает ли он на Python? Кажется, я не могу найти ничего, что конкретно говорит, что это делает или НЕ.
Раньше я работал над PHP-проектом, когда подготовленные операторы делали запросы SELECT на 20% быстрее.
Мне интересно, работает ли он на Python? Кажется, я не могу найти ничего, что конкретно говорит, что это делает или НЕ.
Прямой ответ, нет.
joshperry answer является хорошим объяснением того, что он делает.
Из eugene y ответьте на аналогичный вопрос,
Проверьте MySQLdb Комментарии к пакетам:
"Параметризация" выполняется в MySQLdb путем экранирования строк и затем слепо интерполировать их в запрос, вместо использования MYSQL_STMT API. В результате строки unicode должны проходить через два промежуточные представления (закодированная строка, экранированная строка) прежде чем они будут получены базой данных.
Итак, ответ: Нет, это не так.
Большинство языков предоставляют способ создания общих параметризованных операторов, 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'
После быстрого просмотра метода execute() объекта Cursor пакета MySQLdb (вроде бы де-факто пакет для интеграции с mysql, я думаю), кажется, что (по крайней мере по умолчанию) это только строковая интерполяция и цитирование, а не фактический параметризованный запрос:
if args is not None:
query = query % db.literal(args)
Если это не строковая интерполяция, то что такое?
В случае выполнения он фактически пытается выполнить вставку/замену как один оператор, а не выполнять его в цикле. Что-то об этом, кажется, нет волшебства. По крайней мере, не по умолчанию.
EDIT: О, я только что понял, что оператор modulo можно переоценить, но я почувствовал себя обманом и смазал источник. Однако не найдено переопределения mod
.
Использование интерфейса SQL, предложенное Amit, может работать, если вас беспокоит только производительность. Тем не менее, вы теряете защиту от SQL-инъекции, которую может принести встроенная поддержка Python для подготовленных операторов. Python 3 имеет модули, которые обеспечивают подготовленную поддержку операторов PostgreSQL. Для MySQL "oursql", похоже, обеспечивает истинную поддержку подготовленных операторов (не подделка, как в других модулях).
Для людей, просто пытающихся понять это, ДА вы можете использовать подготовленные инструкции с Python и MySQL. Просто используйте MySQL Connector/Python из самого MySQL и создайте правильный курсор:
https://dev.mysql.com/doc/connector-python/en/index.html
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html
Не связанный напрямую, но этот ответ на другой вопрос в SO включает в себя подробности синтаксиса "templated" запросов. Я бы сказал, что автоматическое экранирование будет их самой важной функцией...
Что касается производительности, обратите внимание на метод executemany
на объекты курсора. Он объединяет несколько запросов и выполняет их все за один раз, что приводит к повышению производительности.
Существует решение!
Вы можете использовать их, если поместить их в хранимую процедуру на сервере и вызвать их как это из python...
cursor.callproc(Procedurename, args)
Вот небольшой учебник по хранимым процедурам в mysql и python.
http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/