プリザンターとPostgreSQL 15

本記事は [OSSのノーコード・ローコード開発ツール「プリザンター」のカレンダー \| Advent Calendar 2022 \- Qiita](https://qiita.com/advent-calendar/2022/pleasanter) の14日目の記事です。

## ご注意ください

本エントリはプリザンター ver.1.3.44.0 でPostgreSQL 15に対応したことにより内容が現在とは違うものになっています。
プリザンター ver.1.3.43.0以前の情報であることにご注意ください。

## はじめに

PostgreSQLが15へメジャーバージョンアップしました。

https://www.postgresql.jp/node/404

さっそくプリザンターと組み合わせてみましょう。

## CodeDefinerがエラーになる

いきなりですがCodeDefinerを実行するとエラーになります。

こんな感じです。(実際はこのエラーがテーブル数分出力されます)

```text
<INFO> TablesConfigurator.ConfigureTableSet: AutoNumberings
<INFO> Tables.CreateTable: AutoNumberings
<ERROR> <>c__DisplayClass0_0.<Configure>b__0: [AutoNumberings]: Npgsql.PostgresException (0x80004005): 42501: permission denied for schema public

POSITION: 20
   at Npgsql.Internal.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|221_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteNonQuery()
   at Implem.PostgreSql.PostgreSqlCommand.ExecuteNonQuery() in /src/Rds/Implem.PostgreSql/PostgreSqlCommand.cs:line 133
   at Implem.Libraries.DataSources.SqlServer.SqlIo.<>c__DisplayClass13_0.<ExecuteNonQuery>b__0() in /src/Implem.Libraries/DataSources/SqlServer/SqlIo.cs:line 113
   at Implem.Libraries.DataSources.SqlServer.SqlIo.Try(ISqlObjectFactory factory, Action action) in /src/Implem.Libraries/DataSources/SqlServer/SqlIo.cs:line 287
   at Implem.Libraries.DataSources.SqlServer.SqlIo.ExecuteNonQuery(ISqlObjectFactory factory, IDbTransaction dbTransaction, IDbConnection dbConnection) in /src/Implem.Libraries/DataSources/SqlServer/SqlIo.cs:line 110
   at Implem.Libraries.DataSources.SqlServer.SqlIo.ExecuteNonQuery(ISqlObjectFactory factory, SqlStatement sqlStatement, IDbTransaction dbTransaction, IDbConnection dbConnection) in /src/Implem.Libraries/DataSources/SqlServer/SqlIo.cs:line 311
   at Implem.CodeDefiner.Functions.Rds.Parts.Tables.CreateTable(ISqlObjectFactory factory, String generalTableName, String sourceTableName, TableTypes tableType, IEnumerable`1 columnDefinitionCollection, IEnumerable`1 tableIndexCollection, EnumerableRowCollection`1 rdsColumnCollection, String tableNameTemp) in /src/Implem.CodeDefiner/Functions/Rds/Parts/Tables.cs:line 36
   at Implem.CodeDefiner.Functions.Rds.TablesConfigurator.ConfigureTablePart(ISqlObjectFactory factory, String generalTableName, String sourceTableName, TableTypes tableType, IEnumerable`1 columnDefinitionCollection) in /src/Implem.CodeDefiner/Functions/Rds/TablesConfigurator.cs:line 115
   at Implem.CodeDefiner.Functions.Rds.TablesConfigurator.ConfigureTableSet(ISqlObjectFactory factory, String generalTableName) in /src/Implem.CodeDefiner/Functions/Rds/TablesConfigurator.cs:line 86
   at Implem.CodeDefiner.Functions.Rds.TablesConfigurator.<>c__DisplayClass0_0.<Configure>b__0(String generalTableName) in /src/Implem.CodeDefiner/Functions/Rds/TablesConfigurator.cs:line 19
  Exception data:
    Severity: ERROR
    SqlState: 42501
    MessageText: permission denied for schema public
    Position: 20
    File: aclchk.c
    Line: 3650
    Routine: aclcheck_error
```

ポイントはここです。

> `MessageText: permission denied for schema public`

## 何が起きているのか

日本語プレスキットの「その他の主な変更点」のセクションに記載があります。

https://www.postgresql.org/about/press/presskit15/ja/

引用しますと、

> PostgreSQL 15では、public（またはデフォルト）スキーマのデータベース所有者を除くすべてのユーザからCREATE権限を剥奪します。

とあります。

ではどうすればいいのでしょうか。

## 解決方法

こちらのエントリがとても参考になります。

https://dev.classmethod.jp/articles/postgresql-15-revoke-create-on-public-schema/

エントリにあるようにpublicスキーマをセキュアに運用するための手順、[「セキュアなスキーマの使用パターン」](https://www.postgresql.org/docs/15/ddl-schemas.html#DDL-SCHEMAS-PRIV)で推奨されている、ユーザごとにスキーマを割り振るようにします。

ではCodeDefinerを実行する前にスキーマを作りましょう。

```sql
create user "Rds接続文字列に指定しているOwnerユーザ名" with password 'Rds接続文字列に指定しているOwnerのパスワード';
create schema authorization "上記ユーザ名";
create database "サービス名" with owner "上記ユーザ名";
```

例としてデフォルトの`Service.json`の`Name`と`Owner用Rds接続文字列`を使う場合はこうなります。

```sql
create user "Implem.Pleasanter_Owner" with password 'SetAdminsPWD';
create schema authorization "Implem.Pleasanter_Owner";
create database "Implem.Pleasanter" with owner "Implem.Pleasanter_Owner";
```

こうすることで無事CodeDefinerが必要なテーブル類を作成できるようになります。

:::note alert
作成するユーザのパスワードはデフォルトのものから必ず変更して運用してください。
デフォルトのものは使用しないでください。
:::

## 関連情報

- プリザンターをUbuntuにインストールする
  https://pleasanter.org/manual/getting-started-pleasanter-ubuntu

- パラメータ設定：Service.json
  https://pleasanter.org/manual/service-json

- パラメータ設定：Rds.json
  https://pleasanter.org/manual/rds-json