Как подключить PostgreSQL к Django
Как подключить PostgreSQL к Django: psycopg 3, DATABASES, создание базы и пользователя, переменные окружения, перенос данных с SQLite и частые ошибки.
Содержание · 10 разделов
- Зачем переходить с SQLite на PostgreSQL
- Установите PostgreSQL
- Создайте базу и пользователя
- Установите psycopg 3
- Настройте DATABASES
- Пароль — в переменные окружения
- Одна строка подключения: dj-database-url
- Проверьте подключение
- Перенос данных с SQLite на PostgreSQL
- Частые ошибки подключения
- Error loading psycopg2 or psycopg module
- Connection refused / Is the server running on that host
- password authentication failed for user “mysite”
- Peer authentication failed for user “mysite”
- database “mysite” does not exist
- permission denied for schema public
- Частые вопросы
- Почему тесты падают с «permission denied to create database»?
- Как подключиться к облачному PostgreSQL по SSL?
- Как работать со схемой, отличной от public?
- Как сделать резервную копию базы Django?
- Как посмотреть SQL, который Django отправляет в PostgreSQL?
- Итог
Чтобы подключить 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 | Пароль роли |
HOST | localhost, IP или имя сервиса в Docker (db) |
PORT | 5432 по умолчанию; пустая строка — тоже порт по умолчанию |
Дополнительно пригодятся:
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