В то время как хранение данных для приложений больше не считается сложной задачей, это упрощение приводит к тому, что страдает гибкость. Тем не менее, есть хороший компромисс. В этой статье вы будете изучать, как получить доступ к MySQL средствами Python.
Данные образуют основу из всех прикладных программ. В любой области, ядро логики приложения составляют выборка, обработка, хранение и представление данных. Каждый из эти этапов эволюционировал в специализированную область знаний.
Если хранение - это контекст, то все от сохранения данных в файл до сохранения данных в базу данных может стать частью базовой логики. На заре эпохи программирования, любой уровень хранения данных считался усложненным, особенно в базах данных. Однако в этой эре Очень Высокоуровневых Языков Программирования (ОВЯП), сложность стала вещью прошедшего времени (почти).
Главная проблема с ОВЯП - то, что большинство из них жертвуют гибкостью ради простоты. Равновесие между гибкостью и простотой должно существовать таким образом, чтобы приложениям, связанным с данными, не нужно было называть усложненным или не дружелюбными к пользователью. Это та ситуация, где языки вроде Python играют центральную роль.
Красота Python в том, что он может обеспечить абстракцию доступа к данным и обработку на различных уровнях. Другими словами, Python предусматривает доступ к базе данных как на уровне SQL, так и на объектном уровне, причем почти к каждому серверу баз данных.
Это оправдывает первую часть заглавия этой статьи. Что до второй части, то из всех реляционных баз данных, MySQL - это лучшее пари. Есть две причины. Первая - MySQL свободен (free). Вторая - MySQL сравнительно не требователен к ресурсам. Отныне, комбинация Python+MySQL - это хороший вариант для связанных приложений, которые жестко привязаны к обработке данных.
В первых секциях этой статьи обсуждаются шаги, требуемые для соединения с и получения данных из MySQL. В последней секции я применю теорию на практике путем демонстрации примера.
Python обеспечил спецификацию API для доступа к серверам баз данных. Эта спецификация находится в его второй версии и известна как DB-API 2.0. Каждому модулю доступа к базе данных придется соответствовать спецификации DB-API 2.0. Почти все модули для RDBMSs соответствуют спецификации. Модуль MySQLdb - это не исключение. Для доступа к MySQL я буду использовать MySQLdb. Нам предстоят четыре шага:

Соединение с базой данных
Создание курсора
Выполнение утверждения SQL
Выборка результатов запроса
Четвертый шаг может влючать любое из этих действий: Создайте, Восстановите, Обновите и Удалите, или СВОУ. Если действие есть Восстановление или проекция в терминах SQL, требуется пятый шаг. Во всех других случаях, требуются только первые четыре, и пятый необязателен. Теперь в деталях:
1. Соединение с базой данных
Таблица входит в состав базы данных. Это особенно верно для MySQL. Чтобы создать таблицу, сначала должна быть создана база данных, или как минимум база данных должна существовать. Чтобы получить данные из таблицы, должно быть установлено соединение с базой данных. Для этого существует метод connect(). Другими словами, connect() - это конструктор MySQLdb. Параметры указаны ниже:
host - это имя системы, где работает сервер MySQL. Это может быть имя DNS или IP адрес. Если никакое значение не передается, то используемое значение по умолчанию - localhost.
user - это пользовательский идентификатор, который должен быть удостоверен. Другими словами, это подлинный идентификатор для использования услуг сервера. Значение по умолчанию - это текущий эффективный пользователь. Большинство времени это или 'nobody', или 'root'.
passwd -- Используя комбинацию пользовательского идентификатора и пароля, сервер (в том чилсе любой другой сервер баз данных) MySQL удостоверяет польователя. Значение по умолчанию - нет пароля. Это подразумевает пустую строку для этого параметра.
db - это имя базы данных, которая должна использоваться, как только установлено соединение с сервером. Однако если база данных, которая используется, не выбрана, установленное соединение бесполезно. Нет никакого значения по умолчанию для этого параметра.
port - это порт, на котором работает сервер. Значение по умолчанию: 3306.
Есть другие параметры, но эти - самые главные и наиболее используемые. Например, чтобы соединиться с базой данных 'test', расположенной на компьютере с именем 'Demo' с пользователем 'root' и паролем 'adm1n':
db= MySQLdb.connect(host='Demo', user='root', passwd='adm1n', db='test')
connect() возвращает объект типа connection. В этом примере db содержит объект connection. Этот объект будет использоваться в следующих шагах.
2. Создание курсора
В терминологии баз данных, курсор - та область памяти, где данные, полученные из таблиц, хранятся после выполнения запроса. В сущности это - рабочая область для базы данных.
MySQL не поддерживает курсоров. Но легко подражать функциональности курсоров. Это то, что делает MySQLdb. Чтобы получить курсор, придется использовать метод cursor() объекта connection . У этого метода только один параметр - класс, который реализует поведение курсора. Это необязательный параметр. Если никакое значение не предоставлено, то по умолчанию устанавливается значение стандартного класса Cursor. Если требуется больше контроля, то может быть представлен пользовательский класс Cursor. Получение курсора:
cursor= db.cursor()
После выполнения этого кода переменная cursor будет содержать объект cursor.
3. Выполнение SQL-запроса
Шаги, перечисленные до сих пор, имели целью установление соединения приложения с базой данных и получение объекта, который симулирует функциональность курсоров. Теперь опишем выполнения SQL-запросов. Любой SQL-запрос, поддерживаемій MySQL, можно выполнить, используя метод класса Cursor execute(). SQL-запрос передается как строка. Как только запрос успешно выполнен, объект Cursor будет содержать результирующий набор полученных значений. Например, чтобы получить все строки таблицы USER_MASTER:
cursor.execute("select * from USER_MASTER")

Как только этот запрос выполнится, объект курсора будет содержать все полученные данные. Это подводит нас к четвертому шагу, получению набора записей. Перед переходом к следующему шагу, мы должны уяснить следующее. Функция execute() принимает и выполняет любой корректный SQL-запрос, в том числе утверждения DDL, как например delete table, изменение alter table, и так далее. В случае утверждений DDL, нет никакого пятого шага (т.е. выборки результатов запроса).
4. Выборка результатов запроса
Гибкость Python проявляется также и в этом шаге. В реальном мире, необходимость получения всех строк таблицы сразу не вероятно. MySQLdb учитывает эту ситуацию, обеспечивая различные версии функция fetch() класса Cursor 2 наиболее используемые версии:
fetchone(): получить одну строку в форме кортежа Python. Все типы данных проецируются в типы данных Python, кроме одного - целое число без знака (unsigned integer). Чтобы избегать любой проблемы переполнения, этот тип проецируется на длинное целое (long).
fetchall(): получить все строки как кортеж кортежей. В то время как fetchone() увеличивает положение курсора на один, fetchall() не делает ничего подобного. В остальном совпадает с предыдущим методом.
Тонкости прояснит следующий пример. Получить один блок за раз и напечатать результат:
numrows = int(cursor.rowcount) # получить общее количество рядов

# получить и показать одну строку за один раз
for x in range(0,numrows):
        row = cursor.fetchone()
        print row[0], "-->", row[1]

Тот же результат может быть достигнут, используя fetchall():
result = cursor.fetchall()

# проходимся по всему набору записей
for record in result:
        print record[0], "-->", record[1]

Итерация осуществляется только через основные API Python. Так как возвращенная структура данных - это кортеж, никакой добавочный API не требуется.
Мы рассмотрели все шаги, требуемые для работы с MySQL. Что я обсудил до сих пор - это "подход удерживания проблемы типа связности базы данных." Однако, в настоящей жизни, возможность повторного использования играет более важную роль, чем в предыдущих примерах. Поэтому в следующей секции я буду использовать предыдущий материал, чтобы создать общий класс для доступа к MySQL.
Выполнение завершено, но что если есть необходимость видеть запрос? В таком случае, добавим к классу отладочную переменную. Эта переменная может принести больше пользы в будущем, если классу нужно быть более многословным в его выдаче и ведении лог-файлов. Если выполняемый запрос - это запрос для выборки (другими словами, select-утверждение), чтобы получить результат требуется функция. В данном случае итератор был бы лучше. Так что давайте добавим итератор и функцию, которая использует его, чтобы возвращать значения по одному:

class GenericDBOP:
          def __init__(self, db, name):
                    self.db = db # соединение с базой данных
                    self.name = name # имя таблицы
                    self.dbc = self.db.cursor() # объект cursor
                     self.debug=1                   

          def __getitem__(self, item):
               self.dbc.execute("select * from %s limit %s, 1" %
                                      (self.name, item))
               return self.dbc.fetchone()

          def _query(self, q):
                if self.debug: print "Query: %s" % (q)
                self.dbc.execute(q)

          def __iter__(self):
            "creates a data set, and returns an iterator (self)"
                        q = "select * from %s" % (self.name)
                        self._query(q)
                         return self  # возвращаем объект Iterator
                                                # методом next()

def next(self):
                        "returns the next item in the data set,
                        or tells Python to stop"
                        r = self.dbc.fetchone()
                        if not r:# тут ошибка обрабатывается
                                    raise StopIteration
                   return r

На этом создание класса завершено. Протестируем его:

if __name__==’__main__’:
         db = MySQLdb.connect(user="user", passwd="passwd",
                    db="library")
         books = GenericDBOP (db, "book")

         for i in xrange(80, 100):
                    print "Book %s: %s" % (i, books[i])

Так как __getitem__() реализован в классе, мы можем обратиться к базе данных как списку Python. Другая функциональность может также быть протестирована таким же образом. Таким образом мы подошли к концу этого обсуждения. Мы убедились, что доступ к базам данных из Python действительно прост.



Постоянные ссылки

При копировании ссылка на TeaM RSN обязательна!

URI

Html (ЖЖ)

BB-код (Для форумов)

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.