Create PostgreSQL ROLE (user) if it doesn't exist

前端 未结 10 1735
旧时难觅i
旧时难觅i 2020-12-12 15:47

How do I write an SQL script to create a ROLE in PostgreSQL 9.1, but without raising an error if it already exists?

The current script simply has:

CR         


        
相关标签:
10条回答
  • 2020-12-12 16:35

    The same solution as for Simulate CREATE DATABASE IF NOT EXISTS for PostgreSQL? should work - send a CREATE USER … to \gexec.

    Workaround from within psql

    SELECT 'CREATE USER my_user'
    WHERE NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'my_user')\gexec
    

    Workaround from the shell

    echo "SELECT 'CREATE USER my_user' WHERE NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'my_user')\gexec" | psql
    

    See accepted answer there for more details.

    0 讨论(0)
  • 2020-12-12 16:39

    Here is a generic solution using plpgsql:

    CREATE OR REPLACE FUNCTION create_role_if_not_exists(rolename NAME) RETURNS TEXT AS
    $$
    BEGIN
        IF NOT EXISTS (SELECT * FROM pg_roles WHERE rolname = rolename) THEN
            EXECUTE format('CREATE ROLE %I', rolename);
            RETURN 'CREATE ROLE';
        ELSE
            RETURN format('ROLE ''%I'' ALREADY EXISTS', rolename);
        END IF;
    END;
    $$
    LANGUAGE plpgsql;
    

    Usage:

    posgres=# SELECT create_role_if_not_exists('ri');
     create_role_if_not_exists 
    ---------------------------
     CREATE ROLE
    (1 row)
    posgres=# SELECT create_role_if_not_exists('ri');
     create_role_if_not_exists 
    ---------------------------
     ROLE 'ri' ALREADY EXISTS
    (1 row)
    
    0 讨论(0)
  • 2020-12-12 16:41

    Or if the role is not the owner of any db objects one can use:

    DROP ROLE IF EXISTS my_user;
    CREATE ROLE my_user LOGIN PASSWORD 'my_password';
    

    But only if dropping this user will not make any harm.

    0 讨论(0)
  • 2020-12-12 16:42

    My team was hitting a situation with multiple databases on one server, depending on which database you connected to, the ROLE in question was not returned by SELECT * FROM pg_catalog.pg_user, as proposed by @erwin-brandstetter and @a_horse_with_no_name. The conditional block executed, and we hit role "my_user" already exists.

    Unfortunately we aren't sure of exact conditions, but this solution works around the problem:

            DO  
            $body$
            BEGIN
                CREATE ROLE my_user LOGIN PASSWORD 'my_password';
            EXCEPTION WHEN others THEN
                RAISE NOTICE 'my_user role exists, not re-creating';
            END
            $body$
    

    It could probably be made more specific to rule out other exceptions.

    0 讨论(0)
提交回复
热议问题