Wie überprüfe ich, ob ein Postgres-Benutzer existiert?


89

createuserErmöglicht die Erstellung eines Benutzers (ROLE) in PostgreSQL. Gibt es eine einfache Möglichkeit zu überprüfen, ob dieser Benutzer (Name) bereits vorhanden ist? Andernfalls kehrt createuser mit einem Fehler zurück:

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

UPDATE: Die Lösung sollte vorzugsweise über die Shell ausführbar sein, damit die Automatisierung innerhalb eines Skripts einfacher ist.

Antworten:


158
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

Und in Bezug auf die Kommandozeile (danke an Erwin):

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

Ergibt 1, wenn gefunden und sonst nichts.

Das ist:

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

Erinnern Sie sich an das integrierte Befehlszeilenprogramm zum Ausführen von SQL? Am Ende würde ich es vorziehen, das Ergebnis nach Möglichkeit auszuführen und von der Shell abzurufen.
m33lky

1
psqlist der Befehl. Aber wenn Sie über das createuserBefehlszeilenprogramm sprechen (Sie haben es offensichtlich getan, ich habe den Platzmangel create userzuerst nicht bemerkt ), ist es möglicherweise einfacher, den Exit-Status zu ignorieren und die Ausgabe an umzuleiten /dev/null.
Michael Krelin - Hacker

2
@ m33lky: Oder Sie können den Rückgabewert dieses Befehls in der Shell testen (als Postgres-Benutzer) : psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Erträge, 1wenn gefunden und sonst nichts.
Erwin Brandstetter

1
Haha, ich habe das nur etwas hässlicher gemacht : echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Fügen Sie Ihre Lösung als Antwort ohne "postgres" nach psql hinzu.
m33lky

2
@ m33lky: Ich habe nur einen Kommentar geschrieben, weil ich denke, dass Michael die Anerkennung für diesen verdient. Er trug den Hauptteil bei. Und er hat sich in der Vergangenheit als guter Sport erwiesen. :) Vielleicht möchte Michael es in seine Antwort aufnehmen?
Erwin Brandstetter

5

Nach der gleichen Idee, als zu überprüfen, ob eine Datenbank vorhanden ist

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

und Sie können es in einem Skript wie diesem verwenden:

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

Dies würde ein größeres Abfrageergebnis als die Antwort stackoverflow.com/a/8546783/107158 erzeugen . Im Gegensatz zu dieser Antwort würde diese jedoch eine Umbenennung in die Systemtabelle überleben pg_roles, jedoch keine Änderung des Befehls \du. Was wird sich am wahrscheinlichsten nicht ändern?
Derek Mahar

3

Hoffe, das hilft denen von euch, die dies in Python tun könnten .
Ich habe ein vollständiges funktionierendes Skript / eine Lösung auf einem GitHubGist erstellt - siehe URL unter diesem Codeausschnitt.

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

Bietet idempotent remote (RDS) PostgreSQL zum Erstellen einer Rolle / eines Benutzers aus Python ohne CM-Module usw.


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"

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.