จะตรวจสอบได้อย่างไรว่ามีผู้ใช้ postgres อยู่หรือไม่?


89

createuserอนุญาตให้สร้างผู้ใช้ (ROLE) ใน PostgreSQL มีวิธีง่ายๆในการตรวจสอบว่ามีผู้ใช้ (ชื่อ) อยู่แล้วหรือไม่? มิฉะนั้น createuser จะส่งกลับพร้อมข้อผิดพลาด:

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

UPDATE: ควรใช้วิธีแก้ปัญหาจากเชลล์เพื่อให้ง่ายต่อการทำงานอัตโนมัติภายในสคริปต์

คำตอบ:


161
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

และในแง่ของบรรทัดคำสั่ง (ขอบคุณ Erwin):

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

ให้ผล 1 หากพบและไม่มีอะไรอื่น

นั่นคือ:

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

คุณจำยูทิลิตี้บรรทัดคำสั่งในตัวเพื่อรัน SQL ได้หรือไม่? ในท้ายที่สุดฉันต้องการดำเนินการและดึงผลลัพธ์จากเชลล์ถ้าเป็นไปได้
m33lky

1
psqlคือคำสั่ง แต่ถ้าคุณกำลังพูดคุยเกี่ยวกับcreateuserอรรถประโยชน์บรรทัดคำสั่ง (คุณเห็นได้ชัดทำผมไม่ได้สังเกตเห็นการขาดพื้นที่ในcreate userตอนแรก) /dev/nullแล้วมันอาจจะง่ายเพียงแค่จะไม่สนใจสถานะออกและการส่งออกที่จะเปลี่ยนเส้นทาง
Michael Krelin - แฮ็กเกอร์

2
@ m33lky: หรือคุณสามารถทดสอบค่าตอบแทนของคำสั่งนี้ในเปลือก (เป็นผู้ใช้ psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'"postgres): ผลตอบแทน1หากพบและไม่มีอะไรอื่น
Erwin Brandstetter

1
ฮ่า ๆ ฉันเพิ่งทำแบบนั้นน่าเกลียดecho "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAMEกว่านี้: . เพิ่มโซลูชันของคุณเป็นคำตอบโดยไม่ต้องใช้ "postgres" หลัง psql
m33lky

2
@ m33lky: ฉันแค่เขียนความคิดเห็นเพราะฉันคิดว่าไมเคิลสมควรได้รับเครดิตในเรื่องนี้ เขามีส่วนร่วมในส่วนหลัก และเขาพิสูจน์แล้วว่าเป็นกีฬาที่ดีในอดีต :) บางทีไมเคิลอาจต้องการรวมไว้ในคำตอบของเขา?
Erwin Brandstetter

5

ทำตามความคิดเดียวกันมากกว่าที่จะตรวจสอบว่ามีฐานข้อมูลอยู่หรือไม่

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

และคุณสามารถใช้ในสคริปต์เช่นนี้:

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

นี้จะสร้างผลแบบสอบถามมีขนาดใหญ่กว่าคำตอบstackoverflow.com/a/8546783/107158 แต่แตกต่างจากคำตอบที่หนึ่งนี้จะมีชีวิตรอดให้เปลี่ยนชื่อตารางระบบแต่ไม่ได้มีการเปลี่ยนแปลงคำสั่งpg_roles \duข้อใดมักไม่เปลี่ยนแปลง
Derek Mahar

3

หวังว่านี้จะช่วยให้บรรดาผู้ที่อาจจะมีการทำเช่นนี้ในหลาม
ฉันสร้างสคริปต์ / โซลูชันที่ใช้งานได้ทั้งหมดบน GitHubGist - ดู URL ด้านล่างข้อมูลโค้ดนี้

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

จัดเตรียม idempotent remote (RDS) PostgreSQL สร้างบทบาท / ผู้ใช้จาก python โดยไม่มีโมดูล CM เป็นต้น


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.