Làm thế nào để kiểm tra xem người dùng postgres có tồn tại không?


89

createusercho phép tạo một người dùng (ROLE) trong PostgreSQL. Có cách nào đơn giản để kiểm tra xem người dùng (tên) đó đã tồn tại chưa? Nếu không, createuser trả về với một lỗi:

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

CẬP NHẬT: Tốt hơn là giải pháp nên được thực thi từ trình bao, để việc tự động hóa bên trong một tập lệnh dễ dàng hơn.

Câu trả lời:


158
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

Và về dòng lệnh (cảm ơn Erwin):

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

Kết quả 1 nếu tìm thấy và không có gì khác.

Đó là:

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

Bạn có nhớ tiện ích dòng lệnh tích hợp để thực thi SQL là gì không? Cuối cùng, tôi muốn thực thi và lấy kết quả từ shell nếu có thể.
m33lky 17/12/11

1
psqllà lệnh. Nhưng nếu bạn đang nói về createusertiện ích dòng lệnh (bạn rõ ràng là vậy, tôi không nhận thấy sự thiếu không gian trong create userlúc đầu), thì có thể dễ dàng hơn chỉ cần bỏ qua trạng thái thoát và chuyển hướng đầu ra đến /dev/null.
Michael Krelin - hacker

2
@ m33lky: Hoặc bạn có thể kiểm tra giá trị trả về của lệnh này trong vỏ (như postgres người sử dụng): psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'". Lợi nhuận 1nếu tìm thấy và không có gì khác.
Erwin Brandstetter

1
Haha, tôi chỉ làm điều đó một cách ít xấu xí hơn: echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME. Thêm giải pháp của bạn làm câu trả lời mà không có "postgres" sau psql.
m33lky

2
@ m33lky: Tôi chỉ viết một bình luận, bởi vì tôi nghĩ rằng Michael xứng đáng được công nhận về điều này. Anh ấy đóng góp phần chính. Và anh ấy đã chứng tỏ là một môn thể thao giỏi trong quá khứ. :) Có lẽ Michael muốn kết hợp nó trong câu trả lời của mình?
Erwin Brandstetter

5

Theo cùng một ý tưởng hơn là để kiểm tra xem một db có tồn tại hay không

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

và bạn có thể sử dụng nó trong một tập lệnh như sau:

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

Điều này sẽ tạo ra một kết quả truy vấn lớn hơn so với answer stackoverflow.com/a/8546783/107158 . Tuy nhiên, không giống như câu trả lời đó, câu trả lời này sẽ tồn tại khi đổi tên thành bảng hệ thống pg_roles, nhưng không phải là một thay đổi đối với lệnh \du. Điều nào có nhiều khả năng không thay đổi?
Derek Mahar

3

Hy vọng điều này sẽ giúp những người bạn có thể đang làm điều này trong python .
Tôi đã tạo một tập lệnh / giải pháp hoạt động hoàn chỉnh trên GitHubGist - xem URL bên dưới đoạn mã này.

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

Cung cấp PostgreSQL từ xa Idempotent (RDS) tạo vai trò / người dùng từ python không có mô-đun CM, v.v.


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"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.