Everything you wanted to know
about the Django framework

Переход на PostgreSQL с MySQL в Django

В этой статье можно узнать о шагах, которые нужно предпринять, чтобы перенести проекты Django с MySQL на PostgreSQL.

База данных MySQL — хорошее начало для маленьких и средних проектов. Она известен и широко используется, имеет хорошую документацию. Также есть отличные клиенты для простого управления, такие как phpMyAdmin (web), HeidiSQL (Windows) или Sequel Pro (macOS).

Когда кто-то начинает задумываться о масштабировании проекта, то нужно выбирать что-то более подходящее. Это должна быть БД, которая быстрая, надежная и поддерживает стандарты ANSI для реляционных баз данных. То, что использует большинство разработчиков Django. И такой базой данных для большинства профессионалов является PostgreSQL. PostgreSQL позволяет использовать несколько специфичных функций от разработчиков, которые не доступны в MySQL, например многомерные массивы, поля JSON, поля пары ключ-значение, специальные нечувствительные к регистру текстовые поля, поля диапазонов, специальные индексы, нормальный полнотекстовый поиск и т.п. Для новичка, который хочет быстро влиться в разработку с использованием PostgreSQL, лучший клиент БД — pgAdmin (macOS, linux, windows ). Он может показаться слишком сложным сначала (по сравнению с клиентами MySQL), но поскольку в Django есть встроенная админка и удобный ORM, не будет частой необходимостью проверять базу данных в ее "родном" формате.

Итак, что нужно для перехода от MySQL к PostgreSQL? Это можно сделать за несколько шагов, с использованием pgloader, чтобы помочь в миграции данных.

1. Подготовка MySQL базы

Негобходимо убедиться, что все миграции проведены:

(env)$ python manage.py migrate --settings=settings.production

Теперь можно сделать копию БД и перейти к миграции данных.

2. Установка pgloader

Установить pgloader можно используя средства дистрибутива или скачать из репозитория и собрать из исходных текстов.

3. Создание пользователя и базы в PostgreSQL

В отличие от MySQL, создание новых пользователей и баз данных PostgreSQL обычно происходит в оболочке, а не в клиенте базы данных.

Создадим пользователя и базу данных с таким же именем myproject.

$ createuser --createdb --password myproject
$ createdb --username=myproject myproject

4. Создание схемы

Свяжите проект с базой данных PostgreSQL в настройках, например:

DATABASES = {
    'postgresql': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': get_secret("DATABASE_NAME"), 'USER': get_secret("DATABASE_USER"),
        'PASSWORD': get_secret("DATABASE_PASSWORD"),
    },
}
DATABASES['default'] = DATABASES['postgresql']

В этом функция get_secret () возвращает конфиденциальную информацию из переменных окружения или текстового файла, который не отслеживается при управлении версиями. Но можно использовать любой свой предпочитаемый метод.

Запуск миграции для создания таблиц и связей в новой базе PostgreSQL:

(env)$ python manage.py migrate --settings=settings.local

5. Создание сценария переноса данных

Pgloader использует конфигурационные файлы с настройками, определяющими, как проводить с миграции. Создаем файл конфигурации myproject.load со следующим содержимым:

LOAD DATABASE
    FROM mysql://mysql_username:mysql_password@localhost/mysql_dbname
    INTO postgresql:///myproject
    WITH truncate, data only, disable triggers, preserve index names, include no drop, reset sequences
    ALTER SCHEMA 'mysql_dbname' RENAME TO 'public' ;

6. Запуск миграции данных

$ pgloader myproject.load

Как правило, вылезет большое количество предупреждений о преобразованиях типов. Обычно это можно проигнорировать, потому что сценарий будет стараться угадывать, как конвертировать данные при импорте. Если происходят ошибки, связанные с дублированием данных или таблиц с внешними ключами с потерянными записями, необходимо исправить проблемы в базе данных MySQL, а затем повторить этот процесс. Для этого нужно очистить базу данных MySQL, обновить локальную копию, заново создать базу данных PostgreSQL с помощью команд dropdb и createdb, запустить Django-миграции, чтобы создать схему базы данных, и снова скопировать данные.

7. Адаптация кода

Когда база данных будет успешно перенесена, необходимо запустить тесты проекта Django и исправить все проблемы, связанные с PostgreSQL. Код, написанный с использованием Django ORM, будет работать без проблем. Скорее всего возникнут проблемы с сырым SQL, методом extra() QuerySet и преобразованиями типов.

Как правило, это примерно такие различия:

  • Строковые значения в запросах PostgreSQL всегда оборачиваются 'одиночными кавычками'.
  • PostgreSQL не конвертирует типы при сравнении значений автоматически, как это делает MySQL. Если используется какой-либо сырой SQL-код, нужно выполнить преобразование перед сравнением, например CAST(blog_post.id AS text) = likes_like.object_id или blog_post.id::text = likes_like.object_id. Последний синтаксис с двумя двоеточиями не понимат MySQL, поэтому, если нужно поддерживать обе базы данных, нужно для каждой версии БД свой код.
  • PostgreSQL чувствителен к регистру для сравнения строк, поэтому в фильтрах QuerySet нужно будет использовать *__iexact поиск вместо *__ exact и *__icontains вместо *__contains.
  • При сортировке преобразовывать столбец в нижний регистр с помощью функции Lower ():
    from django.db import models posts = Post.objects.order_by(models.Lower('title'))
  • При использовании *__in убедиться, что тип перечисленных элементов соответствует типу поля модели. Например, может быть модель Like с общим отношением, то есть content_type и object_id, которые вместе создают общий внешний ключ с любым экземпляром модели. Поле object_id обычно имеет тип строки, но идентификаторы связанных моделей могут быть целыми числами, строками или UUID. Если нужно получить понравившиеся сообщения, первичным ключам которых являются целые числа, нужно преобразовать значения object_id в целые числа, прежде чем назначать их для поиска pk__in в фильтре:

    liked_ids = map(
        int,
        Like.objects.filter(
            user=request.user,
            content_type=ContentType.objects.get_for_model(Post)
        ).values("object_id", flat=True)
    )
    liked_posts = Post.objects.filter(pk__in=liked_ids)

8. Повторить процесс на "боевом" сервере

После удачной локальной миграции можно приступать к миграции рабочего проекта.

Вывод

PostgreSQL имеет больше ограничений по работе с ним, чем MySQL, но обеспечивает большую производительность, большую стабильность и лучшее соответствие стандартам. Кроме того, в PostgreSQL существует множество функций, недоступных в MySQL. Если повезет, то можно перевести проект с MySQL на PostgreSQL за один день.

Поделитесь с другими:

Представления-классы
(Class-Based Views)

Детальное описание и структура классов Django.

Django DetailView - основы использования

Django позволяет создавать приложения очень легко. Если приложение должно быть выпущено быстро и является относительно общим, то эта среда Python идеально подходит для этого. В течение нескольких лет я профессионально работал в этой среде и часто рылся внутри, поэтому знаю почти всё, и сегодня я представлю вам все, что нужно знать, чтобы эффективно использовать универсальный DetailView в Django.

Выпущены исправления Django: 2.2.7, 2.1.14 и 1.11.26

Сегодня команда разработчиков Django выпустила версии 2.2.7, 2.1.14 и 1.11.26 с исправлениями ошибок. Пакет и контрольные суммы доступны на странице загрузок, а также из индекса пакетов Python. Идентификатор ключа PGP, использованный в этом выпуске: Mariusz Felisiak: 2EF56372BA48CD1B.

Как заставить request.is_ajax() работать с JS fetch()

Объект запроса Django request имеет изящный небольшой метод is_ajax(). Он позволяет определить, поступил ли запрос от JS-фреймворка (он же ajax старой школы). Хотя он отлично работает с некоторыми библиотеками JS, включая почтенный jQuery, он не будет работать с современным встроенным в JS fetch().

Практика программирования на Python 3, лекция №5

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №5.

Практика программирования на Python 3, лекция №4

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №4.

Практика программирования на Python 3, лекция №3

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №3.

Практика программирования на Python 3, лекция №2

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №2.

Практика программирования на Python 3, лекция №1

Лекции о Python 3 от Тимофея Хирьянова при поддержке Московского физико-технического института. Лекция №1.

Как загрузить файлы с Django

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

Советы по написанию миграции данных в приложении Django

В приложении Django при изменении схемы Django автоматически создает файл миграции для изменений схемы. Мы можем написать дополнительные миграции для изменения данных. В этой статье мы узнаем несколько советов по написанию миграций данных в приложениях Django.