Перейти к содержанию

Подключение к PostgreSQL

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

Рассмотрим соединение с отдельной локальной базой professorweb_lab. Пример предназначен для PostgreSQL 17.11. Он не использует Beget, рабочий ProfessorWeb или какой-либо внешний сервер. Файлы catalog-db/lesson-02 лежат в архиве серии. Пока ничего не выполнялось; описанные ответы ожидаются при будущем ручном повторении.

Сервер, база и роль

Сервер PostgreSQL — процесс, который принимает соединения и управляет хранением. В одном экземпляре могут находиться несколько баз. Роль — учётная сущность PostgreSQL; роль с возможностью входа используется для подключения. Клиент psql не является самой базой: он отправляет команды серверу и показывает ответы. Эти части могут работать на одном компьютере, оставаясь разными участниками обмена. Общую архитектуру описывает документация PostgreSQL.

В договоре серии адрес сервера равен 127.0.0.1, порт — 5432, база — professorweb_lab, роль — professorweb_student. Адрес loopback означает обращение к локальному компьютеру с точки зрения процесса клиента. Если клиент работает внутри контейнера, слово «локальный» уже относится к контейнеру; нельзя без рассуждения переносить ту же строку подключения между средами.

Порт не является названием базы. На одном компьютере два экземпляра PostgreSQL могут слушать разные порты, причём в обоих будет база с одинаковым именем. По этой причине проверка только current_database() недостаточна для подтверждения изоляции. Она полезна как дополнительный барьер в учебных файлах, но место запуска клиента и выбранный адрес всё равно нужно понимать.

Базу и роль предварительно создаёт владелец отдельного локального экземпляра. Учебная роль должна владеть своей базой, но не иметь атрибутов SUPERUSER, CREATEDB и CREATEROLE. Здесь не приводим автоматически выполняемый административный сценарий: его входные данные зависят от вашей установки. Каталог не нуждается в доступе к чужим базам только ради создания своих таблиц.

Явное подключение

Для будущего ручного подключения используется следующая команда. В ней нет сохранённого пароля:

psql -h 127.0.0.1 -p 5432 -U professorweb_student -d professorweb_lab -W

Параметр -W просит клиент запросить пароль. Если ваша локальная настройка использует другой способ аутентификации, сам запрос пароля не меняет правила сервера. Сервер принимает или отклоняет соединение по своей конфигурации. Важная особенность примера — явное указание адреса, роли и базы, чтобы не зависеть незаметно от системного имени пользователя или переменных окружения.

Пароль не нужно добавлять в статью, коммит или общий архив. При вводе через запрос клиента он не становится частью команды в истории терминала. Для постоянной локальной работы PostgreSQL поддерживает password file, но его содержимое остаётся личной конфигурацией, а не учебными данными каталога. Параметры соединения описаны в руководстве libpq.

Установленное соединение ещё не доказывает, что выбран нужный экземпляр. Сначала прочитайте ответ на безопасный запрос:

SELECT current_database(), current_user,
       inet_server_addr(), inet_server_port();
SHOW server_version;

Ожидаются учебное имя базы, учебная роль, loopback-адрес и согласованный порт. Версию следует сопоставить с принятой для серии. Точное оформление таблицы зависит от клиента; здесь важны значения, а не количество пробелов в выводе. Если вы подключились через Unix-сокет, адрес и порт в этих функциях могут быть отсутствующими: это ещё одна причина не подменять понимание подключения простым сравнением строки.

В снимке lesson.sql находятся только такие диагностические чтения. Его можно перечитать без изменения каталога. А reset.sql имеет другой смысл: он удаляет схему catalog с её объектами и создаёт исходные строки заново. Слово reset обозначает потерю изменений внутри учебной схемы, а не безобидное обновление списка в клиенте. Перед запуском такого файла сначала подтверждают изоляцию подключения.

Состояние соединения и команды

Соединение живёт дольше одного SQL-запроса. Внутри него могут сохраняться настройки, открытая транзакция и состояние клиента. Например, настройка часового пояса влияет на представление времени в ответах. В снимках серии явно установлен UTC, чтобы опубликованные моменты показывались предсказуемо. Это настройка вывода текущей сессии, а не перенос самого события во времени.

Команда клиента и команда SQL также различаются. В psql запись \conninfo показывает сведения о подключении, а SELECT передаётся серверу. Если отправить \conninfo через Python-драйвер как SQL, сервер не обязан её понимать. Напротив, запрос к catalog.courses подходит разным клиентам, поскольку это SQL над одним объектом базы.

Когда команда завершилась ошибкой, не всегда нужно сразу повторять её. Сначала выясните слой отказа. Отсутствующий процесс или неверный порт мешают установить соединение. Неверные учётные данные мешают пройти вход. Отсутствующая таблица возникает уже после подключения при разборе конкретного запроса. Эти ситуации имеют разные причины; создание таблицы не исправит неверный адрес сервера.

Полезный контрпример — ошибка relation does not exist при обращении к courses. Она не доказывает, что данные удалены. Возможно, таблица существует как catalog.courses, но текущее пространство поиска другое. В следующем уроке разберём квалифицированные имена. Пока используйте полное имя, чтобы видимый текст запроса отражал выбранную схему.

Ручное чтение снимка

Если вы решите повторить пример позже, сначала изучите README общего архива. Каждый урок содержит собственное восстановление начального набора, поэтому не нужно выполнять всю серию подряд, чтобы прочитать таблицу курсов. Для выполнения файлов в psql README указывает ON_ERROR_STOP=1: клиент должен остановиться при первой ошибке, а не продолжать неудачную подготовку незаметно для читателя.

Это поведение клиента не делает произвольный SQL безопасным. Оно лишь помогает увидеть место остановки. Отдельная база, отдельная роль и проверенное подключение ограничивают учебную работу заранее; guard внутри файла дополнительно сравнивает имя базы. Если рабочий сервер тоже назван professorweb_lab, guard не отличит его автоматически. Поэтому изоляция — свойство всей среды, а не удачно выбранного слова.

Вход и выполнение не имеют одного таймера

Клиент может ограничивать время установления соединения через параметры подключения. Такой предел относится к попытке связаться с сервером, а не автоматически ко всем будущим SQL-командам. Если соединение уже существует, но выборка ждёт ресурс, прежний таймер подключения не объясняет её продолжительность. Для команд и ожиданий рассматриваются отдельные настройки PostgreSQL.

В учебной среде нет причины менять эти настройки ради получения красивого ответа. Сначала требуется понять, на каком шаге возникло ожидание. Быстрое сообщение «не удалось соединиться» и медленно завершившийся SELECT описывают разные события. Журнал приложения также должен различать их, сохраняя полезную причину и не печатая пароль из строки соединения.

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

После корректного восстановления запрос SELECT count(*) FROM catalog.courses должен вернуть шесть. Это число характеризует зафиксированный учебный набор, а не количество материалов ProfessorWeb. Измените выбранную базу в новой сессии и подумайте, какие из уже созданных объектов будут доступны: соединение не переносит таблицы вслед за клиентом. Старый урок ADO.NET показывает подключение другим клиентом; здесь знакомая идея получила явные параметры PostgreSQL.

Оглавление курса.