Урок 52 из 84 · Базы данных

Подготовка к работе

Вспомним, как работает psql. При запуске этой программы без аргументов, она пытается подключиться к локальной базе данных (находящейся на той же машине) с именем, совпадающим с именем текущего пользователя, и делает это, используя роль с этим же именем. Если PostgreSQL установлен верно и Вы еще не создали пользователя в PostgreSQL для своего дефолтного пользователя в Ubuntu, то запуск этой программы в Linux (например, Ubuntu) будет ругаться на отсутствие соответствующей роли:

$ psql
psql: FATAL:  role "pythoneast" does not exist

Эту проблему можно решить, используя команду sudo -u postgres psql. Но это не лучшее решение, как минимум, по двум причинам:

  • Пользователь postgres имеет максимальные права в СУБД. Тот, кто завладеет им, может уничтожить всё. Поэтому конкретные клиенты (приложения или пользователи) никогда не создают базы данных от имени postgres и никогда не работают из под этого пользователя.
  • Придётся постоянно использовать эту конструкцию sudo -u postgres для любых команд, связанных с СУБД.

Если Вы еще не создали роль в PostgreSQL, которая имеет такое же имя, как и пользователь, из под которого вы работаете в Ubuntu, то, давайте, сделаем это:

  1. Посмотрите имя вашего текущего пользователя: whoami:
$ whoami
pythoneast

\2. Создайте роль с таким же именем внутри PostgreSQL, используя команду createuser. Обратите внимание на то, что команду нужно запускать от пользователя postgres, иначе она попробует соединиться с СУБД от имени текущего пользователя, которого там нет:

# Флаг --createdb добавляет нашей роли возможность создавать базы данных. По умолчанию этой возможности нет.
$ sudo -u postgres createuser --createdb pythoneast

# Для удаления пользователя можно воспользоваться командой:
$ dropuser pythoneast

Теперь у нас есть роль в СУБД. Попробуем соединиться с PostgreSQL, используя её. Если Вы уже создали базу данных с таким же названием, как и Ваша роль, то Вы увидите следующее:

$ psql
pythoneast=#

В ином случае получите ошибку:

$ psql
psql: FATAL:  database "pythoneast" does not exist

Cоединение всегда происходит с конкретной базой данных. Эту базу данных можно указать самостоятельно, просто передав один аргумент в psql. Если мы ее не укажем, то система попытается соединить нас с базой данных с названием нашей роли в PostgreSQL. Мы уже знаем, что внутри PostgreSQL создана база postgres. Попробуем подключиться к ней:

$ psql postgres
postgres=#

Соединение удалось. Теперь посмотрим список ролей. Для этого подходит команда \du (Describe Users), которую надо выполнить внутри REPL.

postgres=> \du
List of roles
 Role name  |                         Attributes                         | Member of 
------------+------------------------------------------------------------+-----------
 postgres   | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 pythoneast | Superuser, Create role, Create DB                          | {}

Как видно, в СУБД создано две роли. Одна postgres, другая — та, которую мы самостоятельно добавили ранее.

Для экспериментов нам понадобится база данных и, возможно, даже не одна. Создадим базу данных с именем geeks. Сделать это можно из командной строки (не репла psql!) командой createdb.

# Если запустить эту команду без аргументов,
# то она попытается создать базу данных,
# совпадающую с именем вашего пользователя в системе.
$ createdb geeks

Имя для базы данных выбирается произвольно и обычно совпадает с названием проекта, для которого она создается. Имена баз уникальны в рамках одной СУБД. Это значит, что повторный вызов createdb с тем же именем приведёт к ошибке.

После установки, PostgreSQL сразу создаёт несколько служебных баз данных (например, postgres), которые нужны для работы самой СУБД.

# Посмотреть список баз данных
$ psql -l

List of databases
    Name    |   Owner    | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+------------+----------+-------------+-------------+-----------------------
 geeks      | pythoneast | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres   | postgres   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 pythoneast | postgres   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0  | postgres   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |            |          |             |             | postgres=CTc/postgres
 template1  | postgres   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |            |          |             |             | postgres=CTc/postgres
(5 rows)

Теперь у нас есть роль и база данных для экспериментов. Подключение к этой БД выполняется так:

$ psql geeks
geeks=#

Созданную базу данных можно удалить командой dropdb:

$ dropdb geeks

Не забудьте её снова создать, так как она понадобится нам в дальнейшем.

Запускать такую команду нужно с большой осторожностью. Удаление базы данных — необратимый процесс. Нет ничего страшнее, чем потерять данные, которые, в отличие от кода, невозможно восстановить без резервных копий. Во избежание недоразумений, команда dropdb не работает без аргументов — ей всегда нужно передавать имя базы.

Удаление базы данных возможно только в том случае, если к ней никто не подключен (за исключением того, кто удаляет). Если есть другие клиенты, например psql или pgadmin4, то СУБД предупредит о невозможности выполнить команду.

Отзыв