Я работал над проектом PHP ранее, где подготовленные операторы сделали Запросы Select на 20% быстрее.
Я задаюсь вопросом, работает ли это над Python? Я, может казаться, не нахожу ничего, что конкретно говорит, что делает или НЕ делает.
Большинство языков предоставляют способ делать общие параметризованные утверждения, Python ничем не отличается. При использовании параметризованного запроса базы данных, поддерживающие готовые операторы, будут делать это автоматически.
На питоне параметризованный запрос выглядит следующим образом:
cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])
Стиль параметризации может отличаться в зависимости от вашего драйвера, вы можете импортировать db-модуль и затем распечатать yourmodule.paramstyle.
Из PEP-249:
paramstyle
Строковая константа, указывающая тип маркера параметра форматирование, ожидаемое интерфейсом. Возможные значения [2]: Стиль вопросительного знака "qmark", например: "...Где имя=? Числовой' Числовой, позиционный стиль, например: "...Где имя=:1 'name' Названный стиль, например, "...Где имя=имя"... Коды формата ANSI C printf, например: "...Где имя=%s Коды расширенного формата 'пиформата' Python, например, "...Где имя=%(имя)s
Не имеет прямого отношения, но этот ответ на другой вопрос в SO включает в себя синтаксические подробности "шаблонных" запросов. Я бы сказал, что автоэскапирование было бы их важнейшей особенностью...
Что касается производительности, обратите внимание на метод executemany
на объектах с курсорами. Он связывает несколько запросов и выполняет их все за один раз, что делает , что приводит к лучшей производительности.
После беглого просмотра метода execute() объекта Cursor пакета MySQLdb (наверное, это своего рода де-факто пакет для интеграции с mysql), кажется, что (по крайней мере, по умолчанию) она делает только строковую интерполяцию и кавычки, а не фактический параметризованный запрос:
if args is not None:
query = query % db.literal(args)
Если это не строковая интерполяция, то что же это?
В случае выполнения, она на самом деле пытается выполнить вставку/замену как одно утверждение, в отличие от выполнения его в цикле. Вот и все, похоже, никакой магии нет. По крайней мере, не в его поведении по умолчанию.
EDIT: О, я только что понял, что оператор modulo может быть переопределен, но я почувствовал, как будто обманываю и смазываю исходный текст. Но нигде не нашел переопределения mod
.
Использование интерфейса SQL, предложенного Амитом, может работать, если вас беспокоит только производительность. Однако тогда вы теряете защиту от SQL-инъекций, которую может обеспечить встроенная поддержка Python для подготовленных операторов. В Python 3 есть модули, которые обеспечивают поддержку подготовленных операторов для PostgreSQL. Для MySQL «oursql», по-видимому, обеспечивает настоящую поддержку подготовленных операторов (а не подделку, как в других модулях).