Як перевірити, чи існує користувач postgres?


89

createuserдозволяє створити користувача (ROLE) в PostgreSQL. Чи існує простий спосіб перевірити, чи вже існує цей користувач (ім'я)? В іншому випадку createuser повертається з помилкою:

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

ОНОВЛЕННЯ: Рішення повинно виконуватися з оболонки переважно, щоб було простіше автоматизувати всередині сценарію.

Відповіді:


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

Дотримуючись тієї самої ідеї, ніж перевірити, чи існує db

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 тощо.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.