Работа с MySQL в Python

Ранее я уже писал статью про работу с PostgreSQL из Python. Сегодняшний пост будет посвящен другой популярной базе данных MySQL. Мой путь в веб-программирование был классическим: PHP, MySQL и Apache. Среди php-разработчиков MySQL пользуется большей популярностью чем PostgreSQL, хотя последняя предоставляет функционал намного богаче. MySQL до сих пор остаётся лидером среди реляционных open source баз данных, поэтому давайте узнаем как с ней работать через Python.

Установка

В статье речь пойдёт про пакет PyMySQL, это реализация mysql-клиента на чистом Python, поэтому никакие дополнительный Си-библиотеки ставить не придётся. Пакет поддерживает работу с Python 2.7 и Python >= 3.5.

Для установки библиотеки выполняем стандартную команду:

pip install PyMySQL

Начало работы

Соединиться с базой можно вот так:

import pymysql
from pymysql.cursors import DictCursor
connection = pymysql.connect(
    host='localhost',
    user='user',
    password='password',
    db='iata',
    charset='utf8mb4',
    cursorclass=DictCursor
)
...
connection.close()

Обратите внимание, что я импортировал класс DictCursor и передал его в вызов функции connect, это нужно для того, чтобы получить результат в виде словаря, где ключами будут названия колонок. Если вам удобно работать с tuple, то ничего не передавайте в cursorclass

Рекомендуется всегда явно закрывать открытое с базой MySQL соединение, путём вызова метода close у объекта connection. Чаще всего разработчики прибегают к конструкции try/finally, но я использую closing из contextlib. Вот как это выглядит:

from contextlib import closing
import pymysql
from pymysql.cursors import DictCursor
with closing(pymysql.connect(...)) as connection:
    ...

В этом случае при выходе из контекстного блока автоматически будет вызван метод close. Чтобы начать взаимодействие с MySQL, необходимо создать курсор:

with closing(pymysql.connect(...)) as connection:
    with connection.cursor() as cursor:
        query = """
        SELECT
            airport_code
        FROM
            airports
        ORDER BY 
            airport_code DESC
        LIMIT 5
        """
        cursor.execute(query)
        for row in cursor:
            print(row)
{'airport_code': 'ZZW'}
{'airport_code': 'ZZU'}
{'airport_code': 'ZZO'}
{'airport_code': 'ZZG'}
{'airport_code': 'ZYR'}

Пишем в базу

А вот как выглядит INSERT в простенькую таблицу с одной колонкой. Описание схемы таблицы следующее:

CREATE TABLE IF NOT EXISTS tweets (
    tweet VARCHAR(254)
)  ENGINE=INNODB;

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

with closing(pymysql.connect(...)) as conn:
    with conn.cursor() as cursor:
        tweets = [
            'Hello world!',
            'I love Python & MySQL',
            'Let\'s start programming ASAP',
            'Python is the coolest programming language'
        ]
        query = 'INSERT INTO tweets (tweet) VALUES (%s)'
        cursor.executemany(query, tweets)
        # необходимо, т.к. по-умолчанию commit происходит только после выхода
        # из контекстного менеджера иначе мы бы не увидели твиттов
        conn.commit()
    with conn.cursor() as cursor:
        query = 'SELECT tweet FROM tweets'
        cursor.execute(query)
        for row in cursor:
            print(row['tweet'])

В выполнения кода получим следующий результат

Hello world!
I love Python & MySQL
Let's start programming ASAP
Python is the coolest programming language