Django-Admin.ru

Как подключить PostgreSQL к Django

Как подключить PostgreSQL к Django: psycopg 3, DATABASES, создание базы и пользователя, переменные окружения, перенос данных с SQLite и частые ошибки.

Редакция Django-Admin.ru
· обновлено · 9 мин чтения

Содержание · 10 разделов
  1. Зачем переходить с SQLite на PostgreSQL
  2. Установите PostgreSQL
  3. Создайте базу и пользователя
  4. Установите psycopg 3
  5. Настройте DATABASES
  6. Пароль — в переменные окружения
  7. Одна строка подключения: dj-database-url
  8. Проверьте подключение
  9. Перенос данных с SQLite на PostgreSQL
  10. Частые ошибки подключения
  11. Error loading psycopg2 or psycopg module
  12. Connection refused / Is the server running on that host
  13. password authentication failed for user “mysite”
  14. Peer authentication failed for user “mysite”
  15. database “mysite” does not exist
  16. permission denied for schema public
  17. Частые вопросы
  18. Почему тесты падают с «permission denied to create database»?
  19. Как подключиться к облачному PostgreSQL по SSL?
  20. Как работать со схемой, отличной от public?
  21. Как сделать резервную копию базы Django?
  22. Как посмотреть SQL, который Django отправляет в PostgreSQL?
  23. Итог

Чтобы подключить PostgreSQL к Django, установите драйвер psycopg 3, создайте в PostgreSQL базу и пользователя и укажите их в настройке DATABASES с движком django.db.backends.postgresql. Затем выполните migrate — Django создаст таблицы в новой базе.

pip install "psycopg[binary]"
# config/settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": "mysite",
        "USER": "mysite",
        "PASSWORD": "надёжный-пароль",
        "HOST": "localhost",
        "PORT": "5432",
    }
}

Ниже — каждый шаг подробно: установка драйвера, создание базы, безопасная передача пароля через переменные окружения, перенос данных со SQLite и разбор ошибок подключения. Инструкция подходит для Django 5.2 LTS и 6.x.

Зачем переходить с SQLite на PostgreSQL

SQLite из коробки удобна для обучения, но в продакшне упирается в ограничения: запись блокирует весь файл базы, а несколько процессов Gunicorn конкурируют за неё. PostgreSQL рассчитан на параллельную работу, а Django поддерживает его возможности: JSONField с поиском по ключам, ArrayField, полнотекстовый поиск из django.contrib.postgres.

Переходить лучше до первого релиза: разработка и продакшн на одной СУБД избавляют от сюрпризов, когда запрос работает на SQLite и падает на PostgreSQL.

Установите PostgreSQL

  • Windows — установщик с postgresql.org (EDB). Запомните пароль пользователя postgres, который мастер попросит задать.
  • Ubuntu/Debian — sudo apt install postgresql. Служба запустится автоматически.
  • macOS — brew install postgresql@18 и brew services start postgresql@18.

Если у вас установлен Docker, PostgreSQL для разработки поднимается одной командой:

docker run --name pg-dev -e POSTGRES_PASSWORD=devpass -p 5432:5432 -d postgres:18

Как собрать Django и PostgreSQL в один docker compose, разобрано в статье «Django в Docker».

Создайте базу и пользователя

Не подключайте Django от имени суперпользователя postgres. Создайте отдельную роль и базу, которой она владеет. Откройте консоль psql:

# Linux
sudo -u postgres psql

# Windows и macOS
psql -U postgres

И выполните SQL:

CREATE USER mysite WITH PASSWORD 'надёжный-пароль';
CREATE DATABASE mysite OWNER mysite;

OWNER mysite важен для PostgreSQL 15 и новее: там у обычных пользователей больше нет права создавать таблицы в схеме public чужой базы. Если база принадлежит роли, под которой работает Django, проблемы нет.

Ещё три настройки роли немного ускоряют подключение: если они уже заданы, Django не выставляет эти параметры при каждом новом соединении:

ALTER ROLE mysite SET client_encoding TO 'utf8';
ALTER ROLE mysite SET default_transaction_isolation TO 'read committed';
ALTER ROLE mysite SET timezone TO 'UTC';

Последняя строка имеет смысл при USE_TZ = True — это значение по умолчанию в новых проектах. Выйти из psql можно командой \q.

Установите psycopg 3

Django работает с PostgreSQL через драйвер psycopg. Начиная с Django 4.2 поддерживается psycopg 3 (пакет psycopg); старый psycopg2 тоже работает, но для новых проектов берите третью версию. Установите её в виртуальное окружение проекта:

pip install "psycopg[binary]"

Вариант [binary] ставит готовую сборку со встроенной библиотекой libpq — ничего компилировать не нужно ни на Windows, ни в Docker. Кавычки нужны, чтобы оболочка (zsh, PowerShell) не пыталась интерпретировать квадратные скобки.

Не забудьте добавить зависимость в requirements.txt:

Django>=5.2
psycopg[binary]>=3.2

Настройте DATABASES

Минимальная настройка показана в начале статьи. Параметры:

КлючЗначение
ENGINEВсегда django.db.backends.postgresql — и для psycopg 3, и для psycopg2
NAMEИмя базы данных
USERРоль PostgreSQL
PASSWORDПароль роли
HOSTlocalhost, IP или имя сервиса в Docker (db)
PORT5432 по умолчанию; пустая строка — тоже порт по умолчанию

Дополнительно пригодятся:

  • CONN_MAX_AGE — сколько секунд держать соединение открытым между запросами (по умолчанию 0: новое соединение на каждый запрос);
  • CONN_HEALTH_CHECKS: True — проверять переиспользуемое соединение перед запросом;
  • "OPTIONS": {"pool": True} — встроенный пул соединений psycopg 3 (Django 5.1+, нужен пакет psycopg[pool]). С пулом CONN_MAX_AGE должен оставаться 0, иначе Django выдаст Pooling doesn't support persistent connections.

Пароль — в переменные окружения

Пароль в settings.py попадёт в git. Читайте параметры из окружения:

# config/settings.py
import os

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "NAME": os.environ.get("POSTGRES_DB", "mysite"),
        "USER": os.environ.get("POSTGRES_USER", "mysite"),
        "PASSWORD": os.environ["POSTGRES_PASSWORD"],
        "HOST": os.environ.get("POSTGRES_HOST", "localhost"),
        "PORT": os.environ.get("POSTGRES_PORT", "5432"),
        "CONN_MAX_AGE": 60,
        "CONN_HEALTH_CHECKS": True,
    }
}

Для пароля значение по умолчанию намеренно не задано: если переменной нет, проект упадёт с KeyError при старте, а не подключится с неверными данными. Задать переменные можно в .env (через python-dotenv или django-environ) или в окружении сервера.

Одна строка подключения: dj-database-url

На хостингах и PaaS базу часто передают одной переменной DATABASE_URL. Пакет dj-database-url превращает её в словарь для DATABASES:

pip install dj-database-url
# config/settings.py
import dj_database_url

DATABASES = {
    "default": dj_database_url.config(
        default="sqlite:///db.sqlite3",
        conn_max_age=600,
        conn_health_checks=True,
    )
}
export DATABASE_URL="postgres://mysite:надёжный-пароль@localhost:5432/mysite"

Спецсимволы в пароле кодируются для URL: @ записывается как %40, : — как %3A.

Проверьте подключение

python manage.py migrate

Если подключение настроено, Django создаст таблицы и выведет Applying ... OK для каждой миграции. Что делает migrate и как работать с миграциями дальше, рассказано в статье «Миграции в Django». Затем создайте администратора — база новая и пустая (см. createsuperuser).

Открыть консоль базы с параметрами из настроек можно командой python manage.py dbshell — для неё в PATH должен быть клиент psql.

Перенос данных с SQLite на PostgreSQL

Если в SQLite уже есть данные, перенесите их через фикстуры Django.

Сначала выгрузите данные, пока проект смотрит на SQLite:

python manage.py dumpdata --natural-foreign --natural-primary -e contenttypes -e auth.Permission -e admin.LogEntry -e sessions --indent 2 -o data.json

Таблицы contenttypes и auth.Permission Django заполняет сам при migrate; если выгрузить и их, loaddata упадёт на дубликатах. Флаги --natural-* сохраняют ссылки на них по именам, а не по ID. Журнал админки и сессии переносить не обязательно.

Важно: используйте -o data.json, а не перенаправление > data.json. В Windows PowerShell 5.1 оператор > сохраняет файл в UTF-16, и loaddata не сможет его прочитать.

Затем переключите DATABASES на PostgreSQL и создайте схему:

python manage.py migrate

После этого загрузите данные:

python manage.py loaddata data.json
# → Installed 1520 object(s) from 1 fixture(s)

Для больших баз (гигабайты) фикстуры работают медленно — тогда смотрите в сторону специализированных инструментов вроде pgloader.

Частые ошибки подключения

Error loading psycopg2 or psycopg module

Драйвер не установлен в то окружение, из которого запускается проект. Активируйте venv и выполните pip install "psycopg[binary]". В Docker проверьте, что пакет есть в requirements.txt и образ пересобран.

Connection refused / Is the server running on that host

connection to server at "127.0.0.1", port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?

Так сообщение выглядит в libpq 14 и новее; на Windows после Connection refused может стоять код ошибки сокета (0x0000274D/10061). PostgreSQL не запущен, слушает другой порт или в HOST указан не тот адрес. Проверьте службу (sudo systemctl status postgresql, на Windows — «Службы»). В Docker Compose хост — это имя сервиса (db), а не localhost: внутри контейнера localhost указывает на сам контейнер.

password authentication failed for user “mysite”

Неверный пароль или имя роли. Смените пароль в psql: ALTER USER mysite WITH PASSWORD 'новый-пароль';. Если пароль приходит из переменной окружения, убедитесь, что она действительно задана в том процессе, где работает Django.

Peer authentication failed for user “mysite”

Linux: в HOST пустая строка, и Django подключается через Unix-сокет, где PostgreSQL сверяет имя системного пользователя. Укажите "HOST": "localhost" — подключение пойдёт по TCP с проверкой пароля.

database “mysite” does not exist

Базу не создали или опечатались в NAME. Список баз в psql — команда \l.

permission denied for schema public

migrate падает с Unable to create the django_migrations table (permission denied for schema public). Это PostgreSQL 15+, а база принадлежит не вашей роли. Сделайте роль владельцем базы:

ALTER DATABASE mysite OWNER TO mysite;
\c mysite
GRANT ALL ON SCHEMA public TO mysite;

Частые вопросы

Почему тесты падают с «permission denied to create database»?

Команда python manage.py test создаёт отдельную базу test_mysite и после прогона удаляет её. Роли, под которой работает Django, нужно право создавать базы — выдайте его в psql:

ALTER USER mysite CREATEDB;

Без этого права тесты останавливаются с сообщением Got an error creating the test database: permission denied to create database.

Как подключиться к облачному PostgreSQL по SSL?

Управляемые базы обычно принимают только шифрованные соединения. Режим SSL передаётся драйверу через OPTIONS:

DATABASES["default"]["OPTIONS"] = {"sslmode": "require"}

Если провайдер выдаёт CA-сертификат, используйте "sslmode": "verify-full" и путь к сертификату в "sslrootcert" — так клиент проверит, что подключается к нужному серверу. В dj-database-url то же самое включает параметр ssl_require=True.

Как работать со схемой, отличной от public?

Задайте путь поиска схем при подключении — таблицы Django будут создаваться и искаться в указанной схеме:

DATABASES["default"]["OPTIONS"] = {"options": "-c search_path=mysite"}

Схему создайте заранее (CREATE SCHEMA mysite AUTHORIZATION mysite;). Альтернатива без правки настроек — ALTER ROLE mysite SET search_path TO mysite;.

Как сделать резервную копию базы Django?

Штатным инструментом PostgreSQL — pg_dump. Сжатый формат -F c восстанавливается командой pg_restore и позволяет выбирать отдельные таблицы:

pg_dump -h localhost -U mysite -F c -f mysite.dump mysite
pg_restore -h localhost -U mysite -d mysite --clean mysite.dump

dumpdata для бэкапов не подходит: на больших объёмах он медленный и сохраняет только данные моделей Django, без индексов, ограничений и объектов базы вне моделей.

Как посмотреть SQL, который Django отправляет в PostgreSQL?

Для одного запроса выведите print(Post.objects.filter(is_published=True).query). При DEBUG = True все выполненные запросы текущего процесса лежат в django.db.connection.queries. Удобнее всего — панель django-debug-toolbar: она показывает каждый запрос страницы, его время и дубликаты.

Итог

Подключение PostgreSQL к Django — это pip install "psycopg[binary]", база с отдельной ролью-владельцем и DATABASES с ENGINE: django.db.backends.postgresql, где пароль читается из окружения. Данные со SQLite переносятся связкой dumpdata → migrate → loaddata. Дальше переходите к работе с данными в шпаргалке по Django ORM, а при подготовке к продакшну — к статье о деплое Django.

  • #Django
  • #PostgreSQL
  • #psycopg
  • #Базы данных
  • #DATABASES
↑ ↓ выборEnter открытьEsc закрыть