GIS開発研究所 > QGISでPostgreSQLビューを編集できない原因|主キーの確認方法

QGISでPostgreSQLビューを編集できない原因|主キーの確認方法

2026年7月26日

5分で読めます

QGISでPostgreSQLビューが読み取り専用になり編集できない原因を、主キー・一意列・ビュー定義・権限の順に切り分けます。編集可能な元テーブルと参照用ビューを分ける安全な構成、INSTEAD OFトリガーを使う際の注意点もSQL例付きで紹介します。

QGIS
PostgreSQL
PostGIS
ビュー
主キー

PostgreSQLで作ったビューをQGISへ追加したところ、鉛筆の編集ボタンが押せなかったり、レイヤー自体を読み込めなかったりすることがあります。SQLでは正しく表示できているのに、QGISでは編集できないと戸惑いますよね。

多くの場合、原因は各行を一意に識別する列がQGISから見えていないことです。ただし、主キーを指定すれば必ず編集できるわけではありません。ビューが更新可能か、権限があるかも順番に確認します。

先に結論:QGISの主キーとPostgreSQLの更新可否を分けて考える

確認するポイントは次の3つです。

  1. QGISが行を一意に識別できる列を指定できるか
  2. PostgreSQL側でそのビューを更新できるか
  3. 接続ユーザーに更新権限があるか

QGISで主キー候補を指定するのは、画面上の地物を見分けるためです。複数テーブルを結合した複雑なビューは、主キー候補があってもPostgreSQL側で直接更新できない場合があります。

QGISで主キー候補を確認する

ビューには、元テーブルのIDを重複させずに含めます。

CREATE VIEW asset_status_view AS
SELECT
  a.id AS asset_id,
  a.asset_code,
  a.asset_name,
  a.status,
  a.geom
FROM assets a
WHERE a.deleted_at IS NULL;

asset_idが重複していないか、NULLがないかを確認します。

SELECT
  count(*) AS total_rows,
  count(asset_id) AS non_null_rows,
  count(DISTINCT asset_id) AS unique_rows
FROM asset_status_view;

3つの件数が同じなら、asset_idを一意列の候補にできます。QGISでPostgreSQL接続からビューを追加するとき、主キー列の選択欄が表示されたらasset_idを指定します。

PostgreSQLビューが更新可能か確認する

単一テーブルを絞り込んだだけの単純なビューは、更新できる場合があります。一方で、次の処理を含むビューは直接更新しにくくなります。

  • 複数テーブルのJOIN
  • GROUP BYや集計関数
  • DISTINCT
  • ウィンドウ関数
  • 複数レコードをまとめた結果

現在の接続ユーザーで更新できるかは、検証用レコードを使ってトランザクション内で確認できます。

BEGIN;

UPDATE asset_status_view
SET status = '確認中'
WHERE asset_id = 1001;

ROLLBACK;

ROLLBACKすれば変更を取り消せますが、本番データで試す前にバックアップと対象IDを確認しましょう。

QGISで編集できない原因を順番に切り分ける

主キー候補が重複している

JOIN先に複数レコードがあると、元テーブルのIDがビュー内で重複します。QGISは同じIDの地物を正しく区別できません。表示用ビューと編集用レイヤーを分ける方法が安全です。

ID列が整数ではない、またはNULLを含む

QGISのバージョンや接続方法によって、主キー候補として扱える型に条件があります。まずは元テーブルの整数主キーをそのままビューへ含める構成を試します。

geometry列にSRIDや型が付いていない

ビュー内で地物を加工すると、geometryの型やSRIDをQGISが正しく判断できない場合があります。必要に応じて型を明示します。

SELECT
  id,
  geom::geometry(Point, 6677) AS geom
FROM assets;

接続ユーザーが読み取り専用

テーブルやビューに対する権限を確認します。

SELECT
  has_table_privilege(current_user, 'public.assets', 'SELECT') AS can_select,
  has_table_privilege(current_user, 'public.assets', 'UPDATE') AS can_update;

権限を追加する場合は、必要なテーブルと操作だけに限定します。広い権限をまとめて付けるのは避けましょう。

複雑なビューは表示専用にする

集計やJOINを多く含むビューは、無理にQGISから直接編集するより、次のように役割を分けると安定します。

  • 地図表示と検索はビュー
  • 属性の更新は元テーブル
  • 履歴の追加は子テーブル
  • 複雑な更新は専用フォームやAPI

QGISのアクション機能やリレーションフォームを使い、表示用ビューから元レコードの編集画面へ移動する方法もあります。

INSTEAD OFトリガーを使う判断

PostgreSQLでは、ビューへの更新を元テーブルへ振り分けるINSTEAD OFトリガーを作れます。ただし、更新ルールがコードとして隠れるため、保守する人が仕組みを理解できる場合に限定した方がよいでしょう。

CREATE FUNCTION update_asset_status_view()
RETURNS trigger AS $$
BEGIN
  UPDATE assets
  SET status = NEW.status
  WHERE id = OLD.asset_id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

実際に使う場合は、対象列、削除、追加、権限、エラー時の動作まで設計する必要があります。

まとめ

QGISでPostgreSQLビューを編集できないときは、次の順で確認します。

  1. 一意でNULLのないID列があるか
  2. geometryの型とSRIDを判断できるか
  3. PostgreSQLでビューを更新できるか
  4. 接続ユーザーに必要な権限があるか
  5. 表示用ビューと編集用テーブルを分けるべきか

**表示に便利なビューと、安全に更新できるデータ構造は別物です。**無理に1レイヤーへまとめず、入力と参照を分けると運用しやすくなります。

QGISとPostGISの編集構成や権限設計でお困りの場合は、GIS開発を無料相談する

参考資料

GISシステム開発・改善支援

既存GISの改善から新規開発まで相談できます

QGIS、PostGIS、GeoServer、MapLibre、GeoDjangoを使った現地調査基盤、Web地図、データ処理を支援します。

GIS開発の無料相談

同期・性能・地図表示の問題を相談できます

QGIS、PostGIS、GeoServer、MapLibre、GeoDjangoの構成を確認し、原因の切り分けと改善順を整理します。

著者
守高 成悟
守高 成悟

代表取締役 CEO

千葉県出身。10歳の頃からプログラミングを始め、ゲーム、Webサイト、ロボット、スマホアプリなどを制作。大阪大学基礎工学部情報科学科で情報工学と統計学を学び、大学時代はAIを研究。大学在学中にWeb広告代理店でのインターンや人材系Webサービスの立ち上げを経験し、卒業後はフリーランスエンジニアとしてGISシステム、データ基盤構築、Webシステムの開発に従事。10年以上のWebアプリ開発・データ分析経験を基に、2023年9月に株式会社ビットライトを設立し、現場業務の仕組み化からデータ基盤構築、データ活用支援までを一気通貫で支援。

運営会社
株式会社ビットライト
株式会社ビットライト

顧客が本当に必要だった価値を、実装する。

現場業務の仕組み化からデータ基盤構築、データ活用支援までを一気通貫で支援しています。

コーポレートサイトを見る