如何检查postgres用户是否存在?


89

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

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

更新:该解决方案应该可以从Shell上执行,因此在脚本内部自动化更容易。

Answers:


158
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中检索结果。
m33lky 2011年

1
psql是命令。但是,如果您谈论的是createuser命令行实用程序(您显然是这样做的,起初我没有注意到其中没有空格create user),那么忽略退出状态并将输出重定向到可能会更容易/dev/null
Michael Krelin-黑客2011年

2
@ m33lky:或者你可以测试在shell命令的返回值(如Postgres的用户) psql postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'"1如果发现,则收益,仅此而已。
欧文·布兰德斯特

1
哈哈,我只是做了,在一个小更丑时尚:echo "SELECT rolname FROM pg_roles WHERE rolname='USR_NAME';" | psql | grep -c USR_NAME。添加您的解决方案作为答案,在psql之后不带“ postgres”。
m33lky 2011年

2
@ m33lky:我只写了一条评论,因为我认为迈克尔值得在此发表评论。他贡献了主要部分。过去,他被证明是一项很好的运动。:)也许迈克尔想把它纳入他的答案?
欧文·布兰德斯特

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大的查询结果。但是,与该答案不同,此答案可以保留到重命名为system表pg_roles而不是更改为command的情况\du。哪个最有可能不变?
德里克·马哈尔

3

希望这对可能在python中执行此操作的人有所帮助。
我在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))

提供幂等远程(RDS)PostgreSQL从python创建角色/用户,而无需CM模块等。


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"

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.