Сообщить об ошибке.

Методы объекта Cursor модуля MySQLdb в Python

Синтаксис:

import MySQLdb

db=MySQLdb.connect(...)
# создание объекта курсора
cursor = db.cursor([cursorclass])

Параметры:

  • cursorclass - необязательный аргумент, класс используемого курсора. По умолчанию используется стандартный класс cursors.Cursor (результат запроса будет возвращаться в виде списка кортежей). Может принимать встроенный класс cursors.DictCursor (результат запроса будет возвращаться в виде словаря, значения ключей - названия столбцов таблицы).

Возвращаемое значение:

Описание:

Объект Cursor представляет собой курсор базы данных, который создается для объекта соединения и используется для управления контекстом операции выборки. Курсоры, созданные из одного и того же соединения, не изолированы, т. е. любые изменения, внесенные в базу данных курсором, немедленно видны другим курсорам. Курсоры, созданные из разных соединений, могут или не могут быть изолированы, в зависимости от того, как реализована поддержка транзакций.

Атрибуты и методы объекта Cursor.


Cursor.arraysize:

Свойство Cursor.arraysize для чтения/записи указывает количество строк, которые нужно извлечь за один раз с помощью Cursor.fetchmany(). По умолчанию равен 1, что означает извлечение одной строки за раз.

Cursor.lastrowid:

Свойство Cursor.lastrowid только для чтения, возвращает id последней измененной строки в таблице (некоторые версии MySQL возвращают идентификатор строки только при выполнении одной операции INSERT). Если операция не может установить идентификатор строки id или если таблица базы данных не имеет столбца id, то этот атрибут возвращает значение None.

Семантика Cursor.lastrowid не определена, если последний выполненный запрос изменил более одной строки, например, при использовании INSERT с Cursor.executemany().

query = "INSERT INTO table (field1, field2, field3) VALUES (%s, %s, %s)"
cursor.execute(query, (param1, param2, param3,))
# получаем `id` вставленной записи
last_id = cursor.lastrowid)

Cursor.rowcount:

Свойство Cursor.rowcount только для чтения, возвращает количество строк, созданных последним Cursor.execute() (для операторов SQL, таких как SELECT), или затронутых (для операторов SQL, таких как UPDATE или INSERT).

Свойство Cursor.rowcount равен -1, если над курсором не было выполнено Cursor.execute() или интерфейс не может определить количество строк последней операции.

Примечание. Будущие версии спецификации Python DB API могут переопределить последний случай, чтобы объект возвращал None вместо -1.

cursor.execute("SELECT spam, eggs, sausage FROM breakfast")
if cursor.rowcount > 0: # если есть результаты
    # то проходимся по списку кортежей с результатами запроса
    for row in cursor.fetchall():
        # извлекаем данные из кортежа с результатами
        spam = row[0]
        eggs = row[1]
        sausage = row[2]

Cursor.rownumber:

Свойство Cursor.rownumber только для чтения, должен возвращать текущий индекс курсора в результирующем наборе, отсчитываемый от 0, или None, если индекс не может быть определен.

Индекс можно рассматривать как индекс курсора в последовательности (результирующем наборе). Следующая операция выборки извлечет строку с индексом Cursor.rownumber в этой последовательности.

Cursor.callproc(procname [, parameters]):

Метод Cursor.callproc() вызывает хранимую процедуру procname с последовательностью аргументов parameters. Возвращает исходные аргументы. Поддержка хранимых процедур работает только с MySQL версии 5.0 и новее.

Примечание о совместимости: PEP-249 указывает, что при наличии параметров OUT или INOUT должны быть возвращены измененные значения. Это не всегда возможно с MySQL. Аргументы хранимой процедуры должны передаваться как переменные сервера и могут быть возвращены только с помощью оператора SELECT. Так как хранимая процедура может возвращать ноль или более наборов результатов, модуль MySQLdb не может определить, есть ли наборы результатов для выборки, прежде чем будут доступны измененные параметры.

Параметры хранятся на сервере как @_*procname*_*n*, где n - позиция аргумента. То есть, если используется cursor.callproc("foo", (a, b, c)), то параметры будут доступны с помощью запроса SELECT @_foo_0 as foo_0, @_foo_1 as foo_1 и @_foo_2 as foo_2.

Примечание о совместимости: Похоже, что выполнение инструкции SQL CALL создает пустой результирующий набор, который появляется после любых результирующих наборов, которые могут быть сгенерированы хранимой процедурой. Таким образом, всегда нужно будет использовать метод Cursor.nextset() для перебора результатов.

Cursor.close():

Метод Cursor.close() немедленно закрывает курсор. Будущие операции будут вызывать исключение `MySQLdb.ProgrammingError'. Если используются курсоры на стороне сервера, то очень важно закрыть курсор, когда он больше не нужен, и особенно перед созданием нового.

Модуль не представляет менеджер контекста для закрытия открытого курсора. Для этих целей можно использовать функцию стандартной библиотеки contextlib.closing().

from MySQLdb import connect
from contextlib import closing

# поднимаем соединение с базой данных
db = connect('user': 'user', 'password': 'password', 'db': 'test_db')

# открываем db.cursor() в менеджере контекста
with closing(db.cursor()) as cursor:
    cursor.execute("SELECT spam, eggs, sausage FROM breakfast")
    ...
    ...

Cursor.info():

Метод Cursor.info() возвращает некоторую информацию о последнем запросе. Обычно этот метод не используется. Если есть какие-либо предупреждения MySQL, то это должно привести к выдаче предупреждения через MySQLdb.Warning и/или предупреждения Python. Также, по умолчанию предупреждение приводит к появлению сообщения на консоли. Можно отфильтровать их или вызвать предупреждение, которое будет выдано как исключение.

Cursor.execute(operation [, parameters]):

Метод Cursor.execute() подготавливает и выполняет operation к базе данных (запрос или SQL-команду). Аргумент parameters могут быть предоставлены в виде кортежа или сопоставления и будут привязаны к переменным в operation. Переменные указываются в нотации, специфичной для базы данных (подробности смотрите в описании аргумента paramstyle функции MySQLdb.connect()).

Ссылка на операцию operation останется за курсором. Если снова передается тот же объект операции, то курсор может оптимизировать свое поведение. Это наиболее эффективно для алгоритмов, в которых используется одна и та же операция, но к ней привязаны разные parameters (много раз).

Возвращает список объектов, представляющие выборку строк таблицы базы данных в зависимости от используемого класса курсора или None, если запрос вернул пустую выборку.

max_price=5
cursor.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))

Cursor.executemany(operation, seq_of_parameters):

Метод Cursor.executemany() подготавливает operation (множественный запрос) к базы данных (запрос или SQL-команду), а затем выполняет его для всех значений последовательности параметров или сопоставлений, найденных в последовательности seq_of_parameters.

Использование этого метода для операции, которая создает один или несколько результирующих наборов, представляет собой неопределенное поведение.

К этому методу применимы те же комментарии, что и для Cursor.execute().

cursor.executemany(
      """INSERT INTO breakfast (name, spam, eggs, sausage, price)
      VALUES (%s, %s, %s, %s, %s)""",
      [
          ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
          ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
          ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
      ] )

Cursor.fetchone():

Метод Cursor.fetchone() получает одну (первую) строку набора результатов запроса, возвращая одну последовательность, или None, если больше нет доступных данных.

Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).

max_price=5
cursor.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))
# получаем первый кортеж из списка 
# кортежей с результатами запроса
row = cursor.fetchone()
# извлекаем результаты из кортежа
spam = row[0]
eggs = row[1]
sausage = row[2]

Cursor.fetchmany([size=cursor.arraysize]):

Метод Cursor.fetchmany() получает следующий набор строк результата запроса, возвращая список кортежей. Когда больше нет доступных строк, то возвращается пустая последовательность.

Количество строк для выборки за вызов определяется аргументом size. Если он не указан, то размер массива курсора определяет количество извлекаемых строк. Метод попытаться получить столько строк, сколько указано аргументом size. Если это невозможно из-за того, что указанное количество строк недоступно, то может быть возвращено меньшее количество строк.

Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).

Обратите внимание, что с аргументом size связаны соображения производительности. Для оптимальной производительности, лучше всего использовать свойство Cursor.arraysize. Если используется аргумент size, то для него лучше сохранять одно и то же значение от одного вызова Cursor.fetchmany() до следующего.

Cursor.fetchall():

Метод Cursor.fetchall() получает все (оставшиеся) строки результата запроса, возвращая их в виде список кортежей.

Обратите внимание, что свойство Cursor.arraysize может повлиять на производительность этой операции.

Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).

cursor.execute("SELECT spam, eggs, sausage FROM breakfast")
# проходимся по списку кортежей с результатами запроса
for row in cursor.fetchall():
    # извлекаем данные из кортежа с результатами
    spam = row[0]
    eggs = row[1]
    sausage = row[2]

Cursor.nextset():

Метод Cursor.nextset() перемещает курсор к следующему набору результатов, отбрасывая оставшиеся строки в текущем наборе результатов. Если дополнительных наборов результатов нет, то возвращается None, в противном случае он возвращает истинное значение.

Обратите внимание, что MySQL не поддерживает несколько наборов результатов до версии 4.1.

Если предыдущий вызов Cursor.execute() не привел к набору результатов или вызов еще не был выполнен, то возникает исключение MySQLdb.Error (или его подкласс).

Cursor.next():

Метод Cursor.next() возвращает следующую строку из выполняемого в данный момент оператора SQL, используя ту же семантику, что и Cursor.fetchone().

Когда набор результатов исчерпан, появляется исключение StopIteration.

Cursor.__iter__():

Метод Cursor.__iter__() возвращает self, чтобы сделать курсоры совместимыми с протоколом итерации.

Cursor.scroll(value [, mode=’relative’ ]):

Метод Cursor.scroll() прокручивает курсор в наборе результатов до новой позиции value в соответствии с режимом mode.Если режим mode='relative' (по умолчанию), то значение берется как смещение к текущей позиции в результирующем наборе, если установлено mode='absolute', то значение указывает абсолютную целевую позицию.

Если операция прокрутки выходит за пределы набора результатов, то возникает исключение IndexError. В этом случае позиция курсора остается неопределенной.

Пример работы с курсором.

Модуль MySQLdb не имеет встроенных менеджеров контекста для закрытия курсора. Для удобной очистки оперативной памяти от результатов объекта курсора лучше использовать функцию стандартной библиотеки contextlib.closing.

from MySQLdb import connect, cursors, Error
from contextlib import closing

# конфигурация соединения с базой данных
MYSQLCONF = {
    'host': 'localhost', # хост базы данных
    'user': '******', # имя пользователя базы данных
    'password': '******', # пароль пользователя базы данных
    'db': 'test_db', # имя базы данных
    'charset': 'utf8', # используемая кодировка базы данных
    'autocommit': True, # автоматический cursor.commit()
    # извлекаемые строки из БД принимают вид словаря
    'cursorclass': cursors.DictCursor
}

# поднимаем соединение с базой данных
db = connect(**MYSQLCONF)

# открываем курсор при помощи `contextlib.closing` 
with closing(db.cursor()) as cursor:
    # создаем строку с запросом с использованием подстановок
    query = """INSERT INTO table (field1, field2, field3) 
               VALUES (%s, %s, %s)"""
    try:
        # выполняем запрос с необходимыми параметрами
        cursor.execute(query, (param1, param2, param3,))
        # здесь должна быть строка с командой `cursor.commit()`
        # но ее нет, т.к. соединение настроено с 'autocommit': True
    except Error as err:
        # Класс `Error` выводит ошибки, связанные с работой базы данных  
        # и не обязательно находящихся под контролем программиста
        print(err)
    # если нужно, то можно получить `id` вставленной записи
    print('lastrowid =>', cursor.lastrowid)

# далее какой-то код программы
...