Урок 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, то, давайте, сделаем это:
- Посмотрите имя вашего текущего пользователя:
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, то СУБД предупредит о невозможности выполнить команду.