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

发布于 2024-12-21 20:15:58 字数 261 浏览 0 评论 0原文

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

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

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

createuser allows creation of a user (ROLE) in PostgreSQL. Is there a simple way to check if that user(name) exists already? Otherwise createuser returns with an error:

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

UPDATE: The solution should be executable from shell preferrably, so that it's easier to automate inside a script.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

別甾虛僞 2024-12-28 20:15:58
SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'

就命令行而言(感谢 Erwin):

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

如果找到则返回 1,除此之外别无其他。

那是:

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

And in terms of command line (thanks to Erwin):

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

Yields 1 if found and nothing else.

That is:

psql postgres -tXAc "SELECT 1 FROM pg_roles WHERE rolname='USR_NAME'" | grep -q 1 || createuser ...
坠似风落 2024-12-28 20:15:58

遵循相同的想法检查数据库是否存在

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

Following the same idea than to check if a db exists

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

and you can use it in a script like this:

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
乄_柒ぐ汐 2024-12-28 20:15:58

要完全在单个 psql 命令中完成此操作:

DO $BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'USR_NAME')
THEN CREATE ROLE USR_NAME;
END IF;
END$;

To do this entirely within a single psql command:

DO $BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'USR_NAME')
THEN CREATE ROLE USR_NAME;
END IF;
END$;
花落人断肠 2024-12-28 20:15:58

psql -qtA -c "\du USR_NAME" | psql -qtA -c "\du USR_NAME" |剪切-d“|” -f 1

[[ -n $(psql -qtA -c "\du ${1}" | cut -d "|" -f 1) ]] &&回显“存在”|| echo“不存在”

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"

女皇必胜 2024-12-28 20:15:58

希望这对那些可能在 python 中执行此操作的人有所帮助。
我在 GitHubGist 上创建了一个完整的工作脚本/解决方案 - 请参阅此代码片段下面的 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))

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

Hope this helps those of you who might be doing this in python.
I created a complete working script/solution on a GitHubGist--see URL below this code snippet.

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

云朵有点甜 2024-12-28 20:15:58

受到接受的答案的启发,不幸的是这对我不起作用(直接psql调用时出错) ,然后我做了这样的事情:

if ! echo "SELECT * FROM pg_roles WHERE rolname='USR_NAME'" | psql -h localhost -U postgres | grep -E "[1-9][0-9]* rows"; then
  # User not found, create it
  if ! echo "CREATE USER USR_NAME WITH PASSWORD 'USR_NAME' CREATEDB SUPERUSER" | psql -h localhost -U postgres; then
    echo "Error creating USR_NAME"
    exit 1
  fi
fi

即使我认为 grep -E "1 rows" 在这里是安全的,因为我们不应该有超过一个同名的用户,我更喜欢保留 grep -乙“[1-9][0-9]* rows” 以获得返回成功的通用“我得到 1 个或多个结果”。
如果失败,我会输入 exit 1 ,因为我所在的脚本需要创建此用户才能正常运行。

Inspired from accepted answer, that unfortunately did not work for me (error on direct psql call), I then did something like this:

if ! echo "SELECT * FROM pg_roles WHERE rolname='USR_NAME'" | psql -h localhost -U postgres | grep -E "[1-9][0-9]* rows"; then
  # User not found, create it
  if ! echo "CREATE USER USR_NAME WITH PASSWORD 'USR_NAME' CREATEDB SUPERUSER" | psql -h localhost -U postgres; then
    echo "Error creating USR_NAME"
    exit 1
  fi
fi

Even if I think grep -E "1 rows" is safe here since we should not have more that one user of same name, I prefer keeping grep -E "[1-9][0-9]* rows" to get a generic "I got 1 or more result(s)" returning success.
And I put exit 1 if it fails because I'm on a script that needs this user created to run properly.

薄情伤 2024-12-28 20:15:58

PHP 的完整片段:

  • 此外,最好在列名“rolname”前面提及系统目录/表名“pg_roles”。像这样:“pg_roles.rolname”。

  • 并提及它,因为它让我困惑:它实际上拼写为“rolname”而不是“rolename”。

// PHP Version 8.1.13
// PostgreSQL 15

try {
    // database connection
    $pdo = new PDO("pgsql:host=$host;port=$port;dbname=$dbname", $dbusername, $dbuserkeyword, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

    if ($pdo) { // went fine

        // a query to ask if user available in table (system catalog) "pg_roles" and column "rolname"
        $myResult = $pdo -> query("SELECT * FROM pg_roles WHERE pg_roles.rolname='{$theuseriamlookingfor}'");

        // retrieve the values from response in an Array
        $myResult = $myResult -> fetchAll();

        // output the first value from that Array
        echo $myResult[0]["rolname"];
    } 

} catch (PDOException $e) {
    // output the error-message
    echo $e->getMessage();
}

A complete snippet for PHP:

  • and furthermore, it might be better to mention the system catalog/table name "pg_roles" in front of the column name "rolname". Like this: "pg_roles.rolname".

  • and to mention it, because it confused me: it is really spelled "rolname" and not "rolename".

// PHP Version 8.1.13
// PostgreSQL 15

try {
    // database connection
    $pdo = new PDO("pgsql:host=$host;port=$port;dbname=$dbname", $dbusername, $dbuserkeyword, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);

    if ($pdo) { // went fine

        // a query to ask if user available in table (system catalog) "pg_roles" and column "rolname"
        $myResult = $pdo -> query("SELECT * FROM pg_roles WHERE pg_roles.rolname='{$theuseriamlookingfor}'");

        // retrieve the values from response in an Array
        $myResult = $myResult -> fetchAll();

        // output the first value from that Array
        echo $myResult[0]["rolname"];
    } 

} catch (PDOException $e) {
    // output the error-message
    echo $e->getMessage();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文