2011-12-17 5 views
70

createuser позволяет создавать пользователя (ROLE) в PostgreSQL. Есть ли простой способ проверить, существует ли этот пользователь (имя) уже? В противном случае CreateUser возвращается с ошибкой:Как проверить, существует ли пользователь postgres?

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

UPDATE: Решение должно быть исполняемым из оболочки предпочтительно, так что легче автоматизировать внутри сценария.

ответ

121
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME' 

И с точки зрения командной строки (спасибо Erwin):

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 ... 
+0

Вы помните, что это встроенная утилита командной строки для выполнения SQL? В конце я предпочел бы выполнить и получить результат из оболочки, если это возможно. – m33lky

+1

'psql' - это команда. Но если вы говорите об утилите командной строки 'createuser' (вы, очевидно, делаете это, я не заметил нехватки места в« создании пользователя »), тогда может быть проще просто игнорировать статус выхода и перенаправить вывод на '/ dev/null'. –

+2

@ m33lky: Или вы можете проверить возвращаемое значение этой команды в оболочке (как пользователь postgres): 'psql postgres -tAc" SELECT 1 FROM pg_roles WHERE rolname = 'USR_NAME' "'. Уходит 1, если найдено, и больше ничего. –

3

Следуя ту же идею, чем к check if a db exists

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 
+0

Это приведет к большему результату запроса, чем ответ http://stackoverflow.com/a/8546783/107158. Однако, в отличие от этого ответа, он выживет при переименовании в системную таблицу 'pg_roles', но не будет изменять команду' \ du'. Что, скорее всего, не изменится? –

2

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

# ref: https://stackoverflow.com/questions/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: https://stackoverflow.com/questions/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)) 

Provides idempotent remote (RDS) PostgreSQL create role/user from python without CM modules, etc.

Смежные вопросы