2011-12-17 23 views
70

createuser permite la creación de un usuario (ROLE) en PostgreSQL. ¿Hay alguna manera simple de verificar si ese usuario (nombre) ya existe? De lo contrario vuelve CreateUser con un error:¿Cómo verificar si existe un usuario postgres?

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

ACTUALIZACIÓN: La solución debe ser ejecutable a partir de la cáscara de preferencia, por lo que es más fácil de automatizar dentro de un script.

Respuesta

121
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME' 

Y en términos de línea de comandos (gracias a Erwin):

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

devuelve 1 si se encuentra y nada más.

Eso es:

psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'" | grep -q 1 || createuser ... 
+0

¿Recuerdas cuál es el SQL incorporado en la utilidad de línea de comandos para ejecutar? Al final, preferiría ejecutar y recuperar el resultado del shell si fuera posible. – m33lky

+1

'psql' es el comando. Pero si estás hablando de la utilidad de línea de comandos 'createuser' (obviamente lo haces, no noté la falta de espacio en' create user' al principio), entonces puede ser más fácil simplemente ignorar el estado de salida y redirigir la salida a '/ dev/null'. –

+2

@ m33lky: O puede probar el valor de retorno de este comando en el shell (como usuario de postgres): 'psql postgres -tAc" SELECCIONAR 1 FROM pg_roles DONDE rolname = 'USR_NAME' "'. Otorga '1' si se encuentra y nada más. –

3

Siguiendo la misma idea que check if a db exists

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

y se puede usar en un script como el siguiente:

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

Esto generaría un resultado de consulta más grande que la respuesta http://stackoverflow.com/a/8546783/107158. Sin embargo, a diferencia de esa respuesta, esta sobreviviría a un cambio de nombre a la tabla del sistema 'pg_roles', pero no a un cambio al comando' \ du'. ¿Qué es más probable que no cambie? –

2

Esperanza esto ayuda a las personas de usted que podría estar haciendo esto en python.
Creé una secuencia de comandos/solución completa en un GitHubGist; consulte la URL debajo de este fragmento de código.

# 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.

Cuestiones relacionadas