【问题标题】:How to check if a postgres user exists?如何检查 postgres 用户是否存在?
【发布时间】:2012-01-22 17:21:19
【问题描述】:

createuser 允许在 PostgreSQL 中创建用户 (ROLE)。有没有一种简单的方法来检查该用户(名称)是否已经存在?否则 createuser 返回错误:

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

更新:该解决方案最好可以从 shell 执行,以便更容易在脚本中实现自动化。

【问题讨论】:

    标签: postgresql shell user-management


    【解决方案1】:
    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 的内置命令行实用程序是什么吗?最后,如果可能的话,我宁愿从 shell 执行并检索结果。
    • psql 是命令。但是,如果您在谈论createuser 命令行实用程序(您显然是这样做的,一开始我没有注意到create user 中缺少空间),那么忽略退出状态并将输出重定向到可能会更容易/dev/null.
    • @m33lky:或者你可以在 shell 中测试这个命令的返回值(作为 postgres 用户):psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'"。如果找到则返回 1,仅此而已。
    • 哈哈,我只是以更丑陋的方式做到了这一点:echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME。在 psql 之后添加您的解决方案作为没有“postgres”的答案。
    • @m33lky:我只写了一条评论,因为我认为 Michael 在这篇评论中值得称赞。他贡献了主要部分。他在过去被证明是一项很好的运动。 :) 也许迈克尔想在他的回答中加入它?
    【解决方案2】:

    遵循与check if a db exists相同的想法

    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。哪个最有可能不会改变?
    【解决方案3】:

    希望这对那些可能在 python 中执行此操作的人有所帮助。
    我在 GitHubGist 上创建了一个完整的工作脚本/解决方案——请参阅此代码 sn-p 下方的 URL。

    # ref: https://stackoverflow.com/questions/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: https://stackoverflow.com/questions/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))
    

    Provides idempotent remote (RDS) PostgreSQL create role/user from python without CM modules, etc.

    【讨论】:

      【解决方案4】:

      psql -qtA -c "\du USR_NAME" | cut -d "|" -f 1

      [[ -n $(psql -qtA -c "\du ${1}" | cut -d "|" -f 1) ]] &amp;&amp; echo "exists" || echo "does not exist"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-26
        • 1970-01-01
        • 2021-04-16
        • 2020-03-21
        • 1970-01-01
        • 2018-01-01
        • 1970-01-01
        相关资源
        最近更新 更多