Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Python: Базы данных > подготовленные выражения для MySQL


Автор: dipsy 5.8.2008, 13:44
смотрю http://mail.python.org/pipermail/db-sig/2006-February/004616.html
письму более 2-х лет.

введено ли в питон создание подготовленных выражений, как стандартная функциональность?

можно ли в python создавать подготовленные выражения для MySQL вообще?

Автор: americanets 5.8.2008, 16:32
Цитата(dipsy @  5.8.2008,  14:44 Найти цитируемый пост)
введено ли в питон создание подготовленных выражений, как стандартная функциональность?

можно ли в python создавать подготовленные выражения для MySQL вообще? 


что ты имеешь ввиду ? 

Код

SELECT * FROM table WHERE pole = 'chtoto' AND ...


то да 

Код

Sql = "SELECT * FROM table WHERE pole = 'chtoto' "
cursor.execute(Sql)

Автор: dvska 5.8.2008, 16:50
dipsy Стандарт см. http://www.python.org/dev/peps/pep-0249/
А реализован он в каждом драйвере по-разному.

Автор: dipsy 6.8.2008, 09:44
americanets, имею в виду операторы mysql вида:
Код
PREPARE some_statement FROM 'SELECT * FROM table WHERE pole =?'
кажется, в java у соединения есть метод prepareStatement, который сначала создаёт подготовленное выражение, а потом его использует

dvska, я смотрел документацию. пишут:
Цитата
.execute(operation[,parameters]) 
            Prepare and execute a database operation 

хотя они и говорят prepare, но реально в коде функции execute выражение не подготавливается, а просто подставляется значение параметров в запрос, после чего запрос выполняется:
Код

        if args is not None:
            query = query % db.literal(args)
        try:
            r = self._query(query)

Автор: americanets 6.8.2008, 11:02
dipsy, а как ты представляешь себе работу Prepare ? 

так и есть подставляет значения

Автор: dipsy 6.8.2008, 13:13
americanets, в питоне просто подставляет значения. 

в java - создаёт подготовленное выражение в базе и уже к нему обращается. 
т.е. к созданному подготовленному выражению можно обратиться по собственному имени в коде java.

после вызова sql запроса prepare, в БД сохраняется распарсенный запрос. соответственно, обрабатывается он быстрее, чем просто запросы.

Автор: americanets 6.8.2008, 13:48
Цитата(dipsy @  6.8.2008,  14:13 Найти цитируемый пост)


в java - создаёт подготовленное выражение в базе и уже к нему обращается. 
т.е. к созданному подготовленному выражению можно обратиться по собственному имени в коде java.

 


не путаешь с хранимыми процедурами ? 

Автор: dipsy 6.8.2008, 15:01
взято с http://www.javable.com/tutorials/tjt/jdbc/basics/prepared.html при помощи кэша google:
Код
PreparedStatement updateSales;
String updateString = "update COFFEES " +
                      "set SALES = ? where COF_NAME like ?";
updateSales = con.prepareStatement(updateString);
int [] salesForWeek = {175, 150, 60, 155, 90};
String [] coffees = {"Colombian", "French_Roast", "Espresso",
                     "Colombian_Decaf", "French_Roast_Decaf"};
int len = coffees.length;
for(int i = 0; i < len; i++) {
                updateSales.setInt(1, salesForWeek[i]);
                updateSales.setString(2, coffees[i]);
                updateSales.executeUpdate();
        }

создаётся поготовленное выражение - суть PREPARE в SQL

Автор: americanets 6.8.2008, 15:17
Код

#!/usr/bin/python
# import MySQL module
import MySQLdb
# connect
db = MySQLdb.connect(host="localhost", user="joe", passwd="secret",
db="db56a")
# create a cursor
cursor = db.cursor()
# dynamically generate SQL statements from  list
cursor.executemany("INSERT INTO animals (name, species) VALUES (%s,
%s)", [  ('Rollo', 'Rat'),  ('Dudley', 'Dolphin'),  ('Mark', 'Marmoset')
])


Добавлено через 24 секунды
http://www.devshed.com/c/a/Python/MySQL-Connectivity-With-Python/5/

Добавлено через 7 минут и 21 секунду
а вот тут лучше http://www.sqlalchemy.org

Автор: dipsy 6.8.2008, 16:33
americanets, фишка не в создании нескольких запросов, а в том, что в БД должен сохраняться распарсенный запрос.
executemany и execute только выполняют запрос, но они его не подготавливают в смысле SQL prepare.

более полно, кусок кода функции execute:
Код
        from types import ListType, TupleType
        from sys import exc_info
        del self.messages[:]
        db = self._get_db()
        charset = db.character_set_name()
        query = query.encode(charset)
        if args is not None:
            query = query % db.literal(args)
        try:
            r = self._query(query)

если бы выполнялась prepare, то query должен был бы модифицироваться. чтобы получалось выражения вида
Код
PREPARE some_statement FROM 'SELECT * FROM table WHERE pole =?'

в функции execute это не происходит. то же и в функции executemany. они не создают подготовленных выражений, они только выполняют запросы.

в SQLAlchemy не нашёл способа создания preparedstatements

Автор: americanets 6.8.2008, 16:41
http://www.zoonman.com/library/mysql_sr_and_t.htm
Цитата(dipsy @  6.8.2008,  17:33 Найти цитируемый пост)
но они его не подготавливают в смысле SQL prepare.


это не от языка зависит, это хранимые процедуры

Код

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;




http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html

Добавлено через 21 секунду
http://www.zoonman.com/library/mysql_sr_and_t.htm

Автор: dipsy 6.8.2008, 17:11
americanets, от языка зависит. в java есть возможность работы с prepare, в python похоже, стандартных возможностей нет.
возможно, что реализуется в ODBC, но мне надо использовать MySQLdb

хранимые процедуры это не подготовленные выражения.
процедуры хранятся в базе постоянно. подготовленные выражения хранятся, видимо, пока открыто соединение

хранимая процедура может содержать логику, переменные, создавать временные таблицы и много ещё чего
подготовленное выражение - для выполнения одного запрос к БД

по аналогии, как реальная функция отличается от функции lambda

Автор: americanets 6.8.2008, 17:20
тут у тебя нет никаких подготовленных запросов

Код

PreparedStatement updateSales;
String updateString = "update COFFEES " +
                      "set SALES = ? where COF_NAME like ?";
updateSales = con.prepareStatement(updateString);
int [] salesForWeek = {175, 150, 60, 155, 90};
String [] coffees = {"Colombian", "French_Roast", "Espresso",
                     "Colombian_Decaf", "French_Roast_Decaf"};
int len = coffees.length;
for(int i = 0; i < len; i++) {
                updateSales.setInt(1, salesForWeek[i]);
                updateSales.setString(2, coffees[i]);
                updateSales.executeUpdate();
        }



у тебя шаблон запроса и массивы данных, они также поставляются только в цикле и получается обычный запрос 

Код

update COFFEES set SALES = 175 where COF_NAME like 'Colombian'


и т д 5 штук вот и все. это просто реализация которая возможна в любом языке

Добавлено через 5 минут и 7 секунд
Код

cursor.executemany("update COFFEES set SALES =%s where COF_NAME like %s", [  ('175', 'Colombian'),  ('150', 'French_Roast'),  ('60', 'Espresso') , ('155','Colombian_Decaf'), ('90','French_Roast_Decaf')
])

Автор: dipsy 6.8.2008, 17:50
да, в этом частном примере с java могу ошибаться.
да, в любом языке может быть реализована работа с шаблонами. и в python она реализована как стандартная функциональность.

но. есть такая конструкция в mysql, как подготовленные выражения
уверен, что есть языки, которые умеют по-умолчанию работать с подготовленными выражениями, а не только с шаблонами.

и мне надо выяснить возможность работы с подготовленными выражениями в python при использовании библиотеки MySQLdb.
если в ближайшее время не найду готового решения, то мне придётся писать эту функциональность (для закрытого проекта)

Автор: americanets 6.8.2008, 17:57
Цитата(dipsy @  6.8.2008,  18:50 Найти цитируемый пост)
что есть языки, которые умеют по-умолчанию работать с подготовленными выражениями


это язык SQl

Автор: dipsy 7.8.2008, 11:07
как минимум PHP умеет делать prepare (см. mysqli). PHP обращается к соответствующей библиотеке C.
работа в C происходит на достаточно низком уровне (ниже уровня SQL запросов)

спорить на эту тему далее не буду. хотите убедиться - смотрите исходники

Добавлено через 8 минут и 38 секунд
в файле исходника mysqli_api.c ищите по mysqli_prepare

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)