Bagaimana cara memeriksa apakah ada pengguna postgres?

89

createusermemungkinkan pembuatan pengguna (ROLE) di PostgreSQL. Apakah ada cara sederhana untuk memeriksa apakah pengguna (nama) sudah ada? Jika tidak, createuser kembali dengan kesalahan:

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

UPDATE: Solusinya sebaiknya dapat dieksekusi dari shell, sehingga lebih mudah untuk mengotomatiskan di dalam skrip.

m33lky.dll
sumber

Jawaban:

161
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

Dan dalam hal baris perintah (terima kasih kepada Erwin):

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

Menghasilkan 1 jika ditemukan dan tidak ada yang lain.

Itu adalah:

psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'" | grep -q 1 || createuser ...
Michael Krelin - peretas
sumber
Apakah Anda ingat apa utilitas baris perintah bawaan untuk menjalankan SQL? Pada akhirnya saya lebih suka mengeksekusi dan mengambil hasilnya dari shell jika memungkinkan.
m33lky
1
psqladalah perintahnya. Tetapi jika Anda berbicara tentang createuserutilitas baris perintah (Anda jelas melakukannya, saya tidak memperhatikan kurangnya ruang create userpada awalnya), maka mungkin lebih mudah hanya untuk mengabaikan status keluar dan mengarahkan keluaran ke /dev/null.
Michael Krelin - hacker
2
@ m33lky: Atau Anda bisa menguji nilai kembali dari perintah ini di shell (sebagai user postgres): psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Hasil 1jika ditemukan dan tidak ada yang lain.
Erwin Brandstetter
1
Haha, aku hanya melakukan itu secara sedikit lebih jelek: echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Tambahkan solusi Anda sebagai jawaban tanpa "postgres" setelah psql.
m33lky
2
@ m33lky: Saya hanya menulis komentar, karena menurut saya Michael pantas mendapatkan pujian untuk yang satu ini. Dia menyumbangkan bagian utama. Dan dia terbukti sebagai olahragawan yang bagus di masa lalu. :) Mungkin Michael ingin memasukkannya ke dalam jawabannya?
Erwin Brandstetter
5

Mengikuti ide yang sama daripada memeriksa apakah db ada

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

dan Anda dapat menggunakannya dalam skrip seperti ini:

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
Matt
sumber
Ini akan menghasilkan hasil kueri yang lebih besar daripada answer stackoverflow.com/a/8546783/107158 . Namun, tidak seperti jawaban itu, yang satu ini akan bertahan dari pg_rolespenggantian nama menjadi tabel sistem , tetapi bukan perubahan ke perintah \du. Mana yang paling mungkin tidak berubah?
Derek Mahar
3

Semoga ini bisa membantu Anda yang mungkin melakukan ini dengan python .
Saya membuat skrip / solusi yang berfungsi lengkap di GitHubGist - lihat URL di bawah cuplikan kode ini.

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

Menyediakan idempotent remote (RDS) PostgreSQL membuat peran / pengguna dari python tanpa modul CM, dll.

cmcc
sumber
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"

Pascal Polleunus
sumber