PostgreSQL 11 min read

PostgreSQLのユーザー作成 ― CREATE USERとCREATE ROLEの違い、\duで一覧、削除できないとき

※この記事にはアフィリエイト広告(プロモーション)が含まれます。

PostgreSQL ではユーザーもグループも「ロール」という1つの仕組みで扱います。CREATE USER は、ログインできるロールを作る CREATE ROLE ... LOGIN の別名です。この記事の出力は PostgreSQL 18.6(Ubuntu 26.04 の標準パッケージ)で採りました。

まず見る(結論)

CREATE USER app1 WITH PASSWORD 'パスワード';
GRANT CREATE ON SCHEMA public TO app1;      -- public に表を作らせるなら
\du                                         -- 一覧
  • CREATE ROLE で作ると LOGIN が付かず、ログインすると role "..." is not permitted to log in
  • PostgreSQL 15 以降、作ったユーザーは public スキーマに表を作れない(permission denied for schema public)
  • 表などを持っているユーザーは DROP USER できない。REASSIGN OWNED → DROP OWNED の後に消す

ユーザーを作る

サーバーに入ったら、スーパーユーザーの postgres で psql を開きます。Ubuntu の標準パッケージなら sudo -u postgres psql です。

CREATE USER app1 WITH PASSWORD 'Passw0rd1';
CREATE ROLE app2 WITH PASSWORD 'Passw0rd2';
CREATE USER App3;

3つとも CREATE ROLE と返ります。一覧は psql の \du で出します。

fsv=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 app1      |
 app2      | Cannot login
 app3      |
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

app2 のまま接続すると次のエラーです。

$ psql -h 127.0.0.1 -U app2 -d fsv
psql: error: connection to server at "127.0.0.1", port 5432 failed: FATAL:  role "app2" is not permitted to log in

ALTER ROLE app2 LOGIN; を実行すると接続できました。CREATE ROLE は、権限をまとめて持たせるグループ用のロールを作るときに使います。

名前は引用符で囲まないと小文字になります。CREATE USER App3 で作られたのは app3 で、psql -U App3 で接続すると password authentication failed for user "App3" になりました。接続時のユーザー名は大文字小文字を区別するので、作るときも接続するときも小文字にそろえます。

同じ名前で作ると ERROR: role "app1" already exists です。

SQL で一覧を出す

SELECT rolname, rolcanlogin, rolsuper, rolcreatedb, rolvaliduntil
  FROM pg_roles WHERE rolname !~ '^pg_' ORDER BY rolname;
 rolname  | rolcanlogin | rolsuper | rolcreatedb | rolvaliduntil
----------+-------------+----------+-------------+---------------
 app1     | t           | f        | f           |
 app2     | f           | f        | f           |
 app3     | t           | f        | f           |
 postgres | t           | t        | t           |

pg_ で始まるのは PostgreSQL が最初から持っている定義済みロール(pg_monitor など)です。これらは消せません(cannot drop role pg_monitor because it is required by the database system)。

シェルから作る

$ sudo -u postgres createuser --login --createdb app4
$ sudo -u postgres psql -c "ALTER USER app4 WITH PASSWORD 'Passw0rd4';"

createuser は中で CREATE ROLE を実行するコマンドです。--pwprompt(-P)を付けるとパスワードを対話で聞かれます。

作ったユーザーで表を作れない

app1 で接続して表を作ります。

$ psql -h 127.0.0.1 -U app1 -d fsv -c "CREATE TABLE t_app1 (id int);"
ERROR:  permission denied for schema public
LINE 1: CREATE TABLE t_app1 (id int);
                     ^

PostgreSQL 15 から、public スキーマに表を作る権限が全員には付かなくなりました。表を作れるようにする方法は3つあります。アプリの表を共有の public にまとめるなら1つ目、ユーザーごとに分けるなら2つ目、アプリ専用のデータベースを用意するなら3つ目です。

やり方 コマンド(postgres で実行)
public に作る権限を付ける GRANT CREATE ON SCHEMA public TO app1;
ユーザー専用のスキーマを作る CREATE SCHEMA app1 AUTHORIZATION app1;
データベースごと持たせる CREATE DATABASE appdb OWNER app1;

ユーザー名と同じ名前のスキーマを作ると、スキーマ名を付けずに作った表はそちらに入ります。search_path の既定が "$user", public のためです。

$ psql -h 127.0.0.1 -U app1 -d fsv -c "CREATE TABLE t_own (id int);"
 schemaname | tablename | tableowner
------------+-----------+------------
 public     | t_app1    | app1
 app1       | t_own     | app1

データベースの所有者にしたユーザー(3つ目)は、そのデータベースの public にも表を作れました。他のユーザーが作った表を読ませる権限は permission denied の記事にまとめています。

パスワードと属性を変える

ALTER USER app1 WITH PASSWORD 'NewPassw0rd1';
ALTER USER app1 VALID UNTIL '2027-03-31';
ALTER USER app1 VALID UNTIL 'infinity';
ALTER USER app1 RENAME TO app1x;

VALID UNTIL はパスワードの有効期限です。過去の日付にすると、正しいパスワードでも password authentication failed for user "app1" で弾かれました。期限切れだという表示は出ないので、パスワードが合っているのに入れないときは pg_roles.rolvaliduntil も見ます。'infinity' で期限なしに戻ります。

パスワード認証の失敗の切り分けは password authentication failed の記事にあります。

ユーザーを消す

DROP USER app1;
ERROR:  role "app1" cannot be dropped because some objects depend on it
DETAIL:  privileges for schema public
owner of table t_app1
owner of schema app1
owner of table app1.t_own

DETAIL に残っているものが並びます。持ち物を別のユーザーに移してから、残った権限を外して消します。

REASSIGN OWNED BY app1 TO postgres;   -- 持ち物を postgres に移す
DROP OWNED BY app1;                   -- 残った権限を外す
DROP USER app1;

移さずに持ち物ごと消してよいなら、DROP OWNED BY app1; だけで表やスキーマも消えます。どちらもデータベース単位で効きます。ユーザーが複数のデータベースに表を持っているなら、それぞれのデータベースに接続して実行します。

関連: PostgreSQLの「permission denied」 / PostgreSQLの「password authentication failed」 / MySQLのユーザー作成と権限付与

PostgreSQL をもっと深く知るための本

PostgreSQL実践入門 ──アーキテクチャ、運用監視、性能改善

技術評論社・2026年2月

アーキテクチャから運用監視・性能改善までを扱う。付録に PostgreSQL 18 の新機能と設定項目の差分がある。

Amazonで見る

[改訂3版]内部構造から学ぶPostgreSQL ―設計・運用計画の鉄則

技術評論社・2022年11月・PostgreSQL 14 ベース

内部構造の理解から、設計と運用計画の立て方を学ぶ。

Amazonで見る

Amazonのアソシエイトとして、FIRE SE は適格販売により収入を得ています。