※この記事にはアフィリエイト広告(プロモーション)が含まれます。
PostgreSQL の権限エラーは、何に対する権限が足りないかがメッセージに出ます。
ERROR: permission denied for table t1
ERROR: permission denied for schema public
ERROR: permission denied for sequence t6_id_seq
最後の語が table か schema か sequence かで、付ける権限が変わります。この記事のログは PostgreSQL 18.6(Ubuntu 26.04 の標準パッケージ)で採りました。表を作るのは postgres、エラーを受けるのは一般ユーザー u1 です。
まず見る(結論)
| エラー | よくある原因 | 付ける権限 |
|---|---|---|
permission denied for table |
表の SELECT / INSERT などが無い | GRANT SELECT ON 表 TO ユーザー |
permission denied for schema public(CREATE TABLE で) |
PostgreSQL 15 以降、public スキーマの CREATE 権限は既定で無い | GRANT CREATE ON SCHEMA public TO ユーザー |
permission denied for schema app(SELECT で) |
表の権限はあるが、スキーマの USAGE が無い | GRANT USAGE ON SCHEMA app TO ユーザー |
permission denied for sequence ..._seq |
serial 列の表に INSERT 権限だけを付けた |
GRANT USAGE ON SEQUENCE ... TO ユーザー |
GRANT ... ON ALL TABLES の後に作った表で permission denied for table |
ALL TABLES は実行した時点の表にしか付かない | ALTER DEFAULT PRIVILEGES |
permission denied for table
postgres が作った表を、権限の無い u1 が読むとこうなります。
SELECT * FROM t1;
ERROR: permission denied for table t1
GRANT SELECT ON t1 TO u1 で読めるようになります。ただし SELECT しか付けていないので、INSERT は同じ permission denied for table t1 になります。メッセージには操作の種類が出ないので、どの操作で落ちたかは実行した SQL で判断します。
表に付いている権限は psql の \dp で見られます。
\dp app.*
Schema | Name | Type | Access privileges |
--------+-----------+----------+----------------------------+
app | t3 | table | postgres=arwdDxtm/postgres+|
| | | u1=r/postgres |
app | t4 | table | |
u1=r/postgres は「postgres が u1 に r(SELECT)を付けた」という意味です。a が INSERT、w が UPDATE、d が DELETE です。t4 のように空欄なら、所有者以外は何もできません。
permission denied for schema public(PostgreSQL 15 以降)
一般ユーザーが CREATE TABLE すると、表を作る先の public スキーマで止まります。
CREATE TABLE t2 (id int);
ERROR: permission denied for schema public
LINE 1: create table t2 (id int)
^
PostgreSQL 14 までは、誰でも public スキーマに表を作れました。15 から PUBLIC への CREATE 権限が外され、public スキーマの所有者も pg_database_owner(そのデータベースの所有者)になりました。18.6 の public スキーマの権限です。
\dn+ public
Name | Owner | Access privileges |
--------+-------------------+----------------------------------------+
public | pg_database_owner | pg_database_owner=UC/pg_database_owner+|
| | =U/pg_database_owner |
=U は PUBLIC(全ユーザー)に USAGE だけが付いていることを示します。C(CREATE)はデータベースの所有者にしかありません。
直し方は2つあります。
- そのユーザーに CREATE を付ける:
GRANT CREATE ON SCHEMA public TO u1;(これでCREATE TABLE t2が通った) - アプリ用のデータベースを作るなら、所有者をアプリのユーザーにする:
CREATE DATABASE appdb OWNER app;。データベースの所有者は最初から CREATE できる
permission denied for schema(表の権限はあるのに)
public 以外のスキーマにある表は、表の SELECT 権限に加えて、スキーマの USAGE 権限が要ります。
-- postgres で実行
CREATE SCHEMA app;
CREATE TABLE app.t3 (id int);
GRANT SELECT ON app.t3 TO u1;
-- u1 で実行
SELECT * FROM app.t3;
ERROR: permission denied for schema app
LINE 1: select * from app.t3
^
GRANT USAGE ON SCHEMA app TO u1; を足すと読めました。
ALL TABLES の GRANT は、後から作った表に効かない
GRANT SELECT ON ALL TABLES IN SCHEMA app TO u1 の後に作った表 t4 は、permission denied for table t4 になりました。ALL TABLES は、実行した時点でスキーマにある表にまとめて付けるだけです。
これから作る表にも付けるには ALTER DEFAULT PRIVILEGES を使います。
ALTER DEFAULT PRIVILEGES IN SCHEMA app GRANT SELECT ON TABLES TO u1;
この後に作った t5 は u1 から読めましたが、先に作っていた t4 は読めないままでした。既にある表には ALL TABLES の GRANT を、これから作る表には DEFAULT PRIVILEGES を使い、両方を実行します。
ALTER DEFAULT PRIVILEGES が効くのは、それを実行したユーザーが作った表だけです(FOR ROLE で別のユーザーを指定できます)。
permission denied for sequence
serial 列の表に INSERT 権限だけを付けると、表ではなくシーケンスで止まります。
-- postgres で実行
CREATE TABLE app.t6 (id serial PRIMARY KEY, v text);
CREATE TABLE app.t7 (id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY, v text);
GRANT INSERT ON app.t6, app.t7 TO u1;
-- u1 で実行
INSERT INTO app.t6 (v) VALUES ('a');
ERROR: permission denied for sequence t6_id_seq
INSERT INTO app.t7 (v) VALUES ('a');
INSERT 0 1
serial は裏でシーケンスを作り、INSERT のたびに nextval() を呼びます。シーケンスは表とは別のオブジェクトなので、GRANT USAGE ON SEQUENCE app.t6_id_seq TO u1; が要ります。GENERATED ... AS IDENTITY の列は、表の INSERT 権限だけで通りました。新しく表を作るなら identity 列にしておくと、この GRANT を忘れる心配がありません。
表が見つからないエラー(relation does not exist)は権限とは別の原因です。「PostgreSQLの「relation does not exist」」で扱っています。