Как проверить, существует ли пользователь postgres?

89

createuserпозволяет создать пользователя (РОЛЬ) в PostgreSQL. Есть ли простой способ проверить, существует ли этот пользователь (имя)? В противном случае createuser вернется с ошибкой:

createuser: creation of new role failed: ERROR:  role "USR_NAME" already exists

ОБНОВЛЕНИЕ: решение должно быть исполняемым из оболочки предпочтительно, чтобы его было легче автоматизировать внутри сценария.

m33lky
источник

Ответы:

161
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

А что касается командной строки (спасибо Эрвину):

psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'"

Дает 1, если найдено, и ничего больше.

То есть:

psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'" | grep -q 1 || createuser ...
Михаил Крелин - хакер
источник
Вы помните, какая встроенная утилита командной строки выполняет SQL? В конце концов, я бы предпочел выполнить и получить результат из оболочки, если это возможно.
m33lky
1
psqlэто команда. Но если вы говорите об createuserутилите командной строки (вы, очевидно, заметили, я сначала не заметил нехватки места create user), тогда может быть проще просто игнорировать статус выхода и перенаправить вывод в /dev/null.
Михаил Крелин - хакер
2
@ m33lky: Или вы можете проверить возвращаемое значение этой команды в оболочке (как пользователь Postgres): psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Урожайность, 1если она найдена, и ничего больше.
Эрвин Брандштеттер
1
Ха - ха, я только что сделал это в чуть более уродливой моды: echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Добавьте свое решение в качестве ответа без "postgres" после psql.
m33lky
2
@ m33lky: Я написал только комментарий, потому что думаю, что Майкл заслуживает похвалы за него. Он сыграл основную роль. И в прошлом он показал себя хорошим спортом. :) Может быть, Майкл хочет включить это в свой ответ?
Эрвин Брандштеттер
5

Следуя той же идее, чем проверить, существует ли БД

psql -t -c '\du' | cut -d \| -f 1 | grep -qw <user_to_check>

и вы можете использовать его в таком скрипте:

if psql -t -c '\du' | cut -d \| -f 1 | grep -qw <user_to_check>; then
    # user exists
    # $? is 0
else
    # ruh-roh
    # $? is 1
fi
матовый
источник
Результат запроса будет больше, чем у ответа stackoverflow.com/a/8546783/107158 . Однако, в отличие от этого ответа, этот останется переименованием в системную таблицу pg_roles, но не при изменении команды \du. Что, скорее всего, не изменится?
Дерек Махар
3

Надеюсь, это поможет тем из вас, кто может делать это на python .
Я создал полный рабочий сценарий / решение на GitHubGist - см. URL-адрес ниже этого фрагмента кода.

# ref: /programming/8546759/how-to-check-if-a-postgres-user-exists
check_user_cmd = ("SELECT 1 FROM pg_roles WHERE rolname='%s'" % (deis_app_user))

# our create role/user command and vars
create_user_cmd = ("CREATE ROLE %s WITH LOGIN CREATEDB PASSWORD '%s'" % (deis_app_user, deis_app_passwd))

# ref: /programming/37488175/simplify-database-psycopg2-usage-by-creating-a-module
class RdsCreds():
    def __init__(self):
        self.conn = psycopg2.connect("dbname=%s user=%s host=%s password=%s" % (admin_db_name, admin_db_user, db_host, admin_db_pass))
        self.conn.set_isolation_level(0)
        self.cur = self.conn.cursor()

    def query(self, query):
        self.cur.execute(query)
        return self.cur.rowcount > 0

    def close(self):
        self.cur.close()
        self.conn.close()

db = RdsCreds()
user_exists = db.query(check_user_cmd)

# PostgreSQL currently has no 'create role if not exists'
# So, we only want to create the role/user if not exists 
if (user_exists) is True:
    print("%s user_exists: %s" % (deis_app_user, user_exists))
    print("Idempotent: No credential modifications required. Exiting...")
    db.close()
else:
    print("%s user_exists: %s" % (deis_app_user, user_exists))
    print("Creating %s user now" % (deis_app_user))
    db.query(create_user_cmd)
    user_exists = db.query(check_user_cmd)
    db.close()
    print("%s user_exists: %s" % (deis_app_user, user_exists))

Предоставляет идемпотентный удаленный (RDS) PostgreSQL для создания роли / пользователя из python без модулей CM и т. Д.

cmcc
источник
1

psql -qtA -c "\du USR_NAME" | cut -d "|" -f 1

[[ -n $(psql -qtA -c "\du ${1}" | cut -d "|" -f 1) ]] && echo "exists" || echo "does not exist"

Паскаль Поллеун
источник