Поддерживает ли Python подготовленные MySQL операторы? - PullRequest
47 голосов
/ 22 декабря 2009

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

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

Ответы [ 7 ]

59 голосов
/ 22 декабря 2009

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

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

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

Конкретный стиль параметризации может отличаться в зависимости от вашего драйвера, вы можете импортировать свой модуль БД и затем сделать 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'
13 голосов
/ 21 июня 2013

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

ответ Джошперри - хорошее объяснение того, что он делает вместо этого.

С Евгений у ответ на похожий вопрос ,

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

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

Так что ответ: нет, это не так.

10 голосов
/ 22 декабря 2009

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

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

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

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

РЕДАКТИРОВАТЬ: О, я только что понял, что оператор по модулю может быть переопределен, но я чувствовал, что обманывает и искал источник. Однако нигде не найдено переопределенного значения mod.

5 голосов
/ 13 августа 2015

Для людей, которые просто пытаются это выяснить, ДА вы можете использовать подготовленные операторы с 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

5 голосов
/ 29 марта 2010

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

1 голос
/ 22 декабря 2009

Не имеет прямого отношения, но этот ответ на другой вопрос в SO включает детали синтаксиса «шаблонных» запросов. Я бы сказал, что авто-экранирование будет их самой важной особенностью ...

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

0 голосов
/ 19 февраля 2016

Есть решение!

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

cursor.callproc(Procedurename, args)

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...