Como verificar se existe um usuário postgres?


89

createuserpermite a criação de um usuário (ROLE) no PostgreSQL. Existe uma maneira simples de verificar se esse usuário (nome) já existe? Caso contrário, createuser retornará com um erro:

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

ATUALIZAÇÃO: A solução deve ser executável do shell de preferência, para que seja mais fácil automatizar dentro de um script.

Respostas:


158
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

E em termos de linha de comando (graças a Erwin):

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

Rende 1 se for encontrado e nada mais.

Isso é:

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

Você se lembra qual é o utilitário de linha de comando embutido para executar SQL? No final, prefiro executar e recuperar o resultado do shell, se possível.
m33lky

1
psqlé o comando. Mas se você está falando sobre createuserutilitário de linha de comando (obviamente, sim, não percebi a falta de espaço create userno início), então pode ser mais fácil simplesmente ignorar o status de saída e redirecionar a saída para /dev/null.
Michael Krelin - hacker de

2
@ m33lky: Ou você pode testar o valor de retorno deste comando no shell (como usuário postgres): psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Rende 1se for encontrado e nada mais.
Erwin Brandstetter

1
Haha, eu só fiz isso de uma forma pouco mais feio: echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Adicione sua solução como uma resposta sem "postgres" após o psql.
m33lky

2
@ m33lky: Só escrevi um comentário, porque acho que Michael merece o crédito por este. Ele contribuiu com a parte principal. E ele provou ser um bom esportista no passado. :) Talvez Michael queira incorporar isso em sua resposta?
Erwin Brandstetter

5

Seguindo a mesma ideia que verificar se existe um banco de dados

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

e você pode usá-lo em um script como este:

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

Isso geraria um resultado de consulta maior do que a resposta stackoverflow.com/a/8546783/107158 . No entanto, ao contrário dessa resposta, esta sobreviveria a uma renomeação para a tabela do sistema pg_roles, mas não a uma mudança para o comando \du. O que provavelmente não mudará?
Derek Mahar

3

Espero que isso ajude aqueles de vocês que podem estar fazendo isso em python .
Eu criei um script / solução de trabalho completo em um GitHubGist - veja a URL abaixo deste trecho de código.

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

Fornece função / usuário de criação de PostgreSQL remoto idempotente (RDS) a partir de python sem módulos CM, etc.


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"

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.