Come verificare se esiste un utente postgres?


89

createuserconsente la creazione di un utente (ROLE) in PostgreSQL. C'è un modo semplice per verificare se quell'utente (nome) esiste già? Altrimenti createuser restituisce un errore:

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

AGGIORNAMENTO: La soluzione dovrebbe essere eseguibile preferibilmente dalla shell, in modo che sia più facile da automatizzare all'interno di uno script.

Risposte:


158
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

E in termini di riga di comando (grazie a Erwin):

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

Restituisce 1 se trovato e nient'altro.

Questo è:

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

Ti ricordi qual è l'utilità della riga di comando integrata per eseguire SQL? Alla fine preferirei eseguire e recuperare il risultato dalla shell, se possibile.
m33lky

1
psqlè il comando. Ma se stai parlando di createuserutilità della riga di comando (ovviamente lo fai, all'inizio non ho notato la mancanza di spazio create user), allora potrebbe essere più semplice ignorare lo stato di uscita e reindirizzare l'output a /dev/null.
Michael Krelin - hacker

2
@ m33lky: Oppure si potrebbe verificare il valore di ritorno di questo comando nella shell (come utente postgres): psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Resa 1se trovato e nient'altro.
Erwin Brandstetter

1
Haha, ho appena fatto che in un po 'più brutto della moda: echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Aggiungi la tua soluzione come risposta senza "postgres" dopo psql.
m33lky

2
@ m33lky: ho scritto solo un commento, perché penso che Michael meriti il ​​merito di questo. Ha contribuito alla parte principale. E ha dimostrato di essere un buon sport in passato. :) Forse Michael vuole incorporarlo nella sua risposta?
Erwin Brandstetter

5

Seguendo la stessa idea che controllare se esiste un db

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

e puoi usarlo in uno script come questo:

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

Ciò genererebbe un risultato di query più grande rispetto alla risposta stackoverflow.com/a/8546783/107158 . Tuttavia, a differenza di quella risposta, questa sarebbe sopravvissuta a una ridenominazione nella tabella di sistema pg_roles, ma non a una modifica al comando \du. Quale è molto probabile che non cambierà?
Derek Mahar

3

Spero che questo aiuti quelli di voi che potrebbero farlo in Python .
Ho creato uno script / soluzione funzionante completo su un GitHubGist - vedi l'URL sotto questo frammento di codice.

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

Fornisce idempotent remote (RDS) PostgreSQL crea ruolo / utente da Python senza moduli CM, ecc.


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"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.