フィールドメタ情報の取り出し方。
-- ★ ここの 'res.partner' を取り出したいモデルに置き換えてください
WITH params AS (
SELECT 'res.partner'::text AS target_model
),
base AS (
SELECT
m.model AS model,
replace(m.model, '.', '_') AS model_table,
f.id AS field_id,
f.name AS field_name,
f.ttype AS ttype,
CASE WHEN f.ttype IN ('many2one','one2many','many2many')
THEN f.relation ELSE NULL END AS relation_model,
COALESCE(f.translate, FALSE) AS translate,
CASE f.state WHEN 'base' THEN 'code'
WHEN 'manual' THEN 'studio'
ELSE 'code' END AS origin,
f.required AS required,
f.field_description AS label_en, -- 英語原文そのまま
f.help AS help_en -- 英語原文そのまま
FROM ir_model m
JOIN ir_model_fields f ON f.model_id = m.id
JOIN params p ON m.model = p.target_model
-- 一時モデルを除外するなら下行を有効化
-- WHERE COALESCE(m.transient, FALSE) = FALSE
),
grp AS (
-- 可視グループの XMLID 配列(必要なければこのCTEと最終SELECTの列を削ってOK)
SELECT
b.field_id,
ARRAY_AGG(DISTINCT (imd.module || '.' || imd.name))
FILTER (WHERE imd.id IS NOT NULL) AS groups_xml_ids
FROM base b
LEFT JOIN ir_model_fields_group_rel rel ON rel.field_id = b.field_id
LEFT JOIN res_groups g ON g.id = rel.group_id
LEFT JOIN ir_model_data imd ON imd.model = 'res.groups' AND imd.res_id = g.id
GROUP BY b.field_id
)
SELECT
b.model,
b.model_table,
b.field_name,
b.ttype,
b.relation_model,
b.translate,
b.required,
b.origin,
b.label_en,
b.help_en,
COALESCE(g.groups_xml_ids, ARRAY[]::text[]) AS groups_xml_ids
FROM base b
LEFT JOIN grp g ON g.field_id = b.field_id
ORDER BY b.field_name;
スキーマ追加
ALTER TABLE portal_fields
ADD COLUMN visibility TEXT NOT NULL DEFAULT 'visible',
ADD CONSTRAINT ck_visibility CHECK (visibility IN ('visible','invisible'));
画面項目とテーブルマッピング
埋められる項目
portal_fields列 | 画面表示名(日本語) | 取得元 / 算出方法 | 補足 |
|---|---|---|---|
model | モデル技術名 | ir_model.model | 例: res.partner |
model_table | モデル物理名(テーブル) | replace(ir_model.model,'.','_') | 例: res_partner |
field_name | フィールド技術名 | ir_model_fields.name | 例: x_customer_rank |
ttype | データ型 | ir_model_fields.ttype | char,integer,many2one等 |
relation_model | 関連モデル | CASE WHEN ttype IN (...) THEN ir_model_fields.relation | リレーション型のみ値あり |
translate | 値の多言語フラグ | ir_model_fields.translate | TRUE=値が多言語(JSON等) |
label_i18n | 表示ラベル(多言語) | {'en_US': ir_model_fields.field_description} | まず英語のみ投入(後段で翻訳補完) |
help_i18n | ヘルプ(多言語) | {'en_US': ir_model_fields.help} | 同上 |
ui_control(必須のみ) | UI制御(必須) | jsonb_build_object('required', ir_model_fields.required) | required以外は未取得 |
groups_xml_ids | 権限グループ(XMLID) | ir_model_fields_group_rel → res_groups → ir_model_data(module.name) | 例: ['base.group_user', …] |
origin | 由来 | CASE ir_model_fields.state WHEN 'base'→'code'/'manual'→'studio' ELSE 'code' | 既存=code、Studio=studio |
code_status | 実装状態 | 固定(例: 'planned') | 初期値として投入 |
notes | 備考 | 手入力/運用で設定 | 任意 |
(オプション)visibility | 表示可否 | ルールで決定(origin='studio' or x_%→visible、他invisible) | スキーマ追加時に有効 |
埋められない項目
portal_fields列 | 画面表示名(日本語) | 理由 / 代替手段 |
|---|---|---|
placeholder_i18n | プレースホルダ(多言語) | DB保持が原則なし。ir_ui_view.arch_db のXML解析やポータル側設定で補完 |
unit_i18n | 単位(多言語) | 同上(ビュー/業務定義依存) |
selection_items | 選択肢リスト(多言語) | 多くはPythonコード定義。DBのみでは不可。→ RPC/コード参照 or ビューXMLから導出 |
default_value | 既定値 | ir.default系や計算式起点。現行クエリ未参照 → 対応テーブル/モデルを別参照 or RPC |
widget | ウィジェット | ビューXML依存(<field widget="...">)。→ ir_ui_view.arch_db をXPath解析 |
ui_control の細部 | UI制御(不可視/読取専用/ドメイン等) | ビューXMLの attrs/modifiers に依存。→ XML解析 or RPCでレンダ後属性を取得 |
画面項目 create
-- 既存テーブルを削除(存在すれば)
DROP TABLE IF EXISTS portal_fields CASCADE;
DROP TABLE IF EXISTS portal_field CASCADE;
-- 日本語カラム版 portal_fields を新規作成
CREATE TABLE portal_fields (
"ID" BIGSERIAL PRIMARY KEY,
-- モデル識別
"モデル技術名" TEXT NOT NULL, -- 例: 'res.partner'
"モデル物理名" TEXT NOT NULL, -- 例: 'res_partner'
-- フィールド識別
"フィールド技術名" TEXT NOT NULL, -- 例: 'x_customer_rank'
"データ型" TEXT NOT NULL, -- char/text/html/integer/float/boolean/selection/many2one/one2many/many2many/date/datetime/monetary/binary
"関連モデル" TEXT, -- many2one/m2m/o2m の相手モデル(不要ならNULL)
-- 多言語UI(ポータル表示用)
"表示ラベル_i18n" JSONB, -- {"ja_JP":"顧客ランク","en_US":"Customer Rank"}
"ヘルプ_i18n" JSONB, -- {"ja_JP":"説明...","en_US":"..."}
"プレースホルダ_i18n" JSONB, -- {"ja_JP":"入力してください", ...}
"単位_i18n" JSONB, -- {"ja_JP":"kg","en_US":"kg"}
"備考_i18n" JSONB, -- 任意:備考も多言語で保持したい場合
-- 値の仕様
"値多言語フラグ" BOOLEAN NOT NULL DEFAULT FALSE, -- 値が多言語(JSON)か
"選択肢" JSONB, -- selection の場合: [{"key":"bronze","label_i18n":{...}}, ...]
"既定値" JSONB, -- 型に応じて
-- UI/制御(将来ビュー生成のヒント)
"ウィジェット" TEXT, -- 例: 'radio','many2one','html'
"UI制御" JSONB, -- {"required":true, "invisible":false, ...}
-- 権限
"権限グループ_xmlid配列" TEXT[], -- 例: ARRAY['base.group_sale_manager', ...]
-- 運用メタ
"由来" TEXT NOT NULL DEFAULT 'portal', -- 'studio' | 'code' | 'portal'
"実装状態" TEXT NOT NULL DEFAULT 'planned', -- 'generated' | 'needs_manual' | 'not_implemented' | 'planned'
"備考" TEXT,
-- 監査
"作成日時" TIMESTAMP NOT NULL DEFAULT now(),
"更新日時" TIMESTAMP NOT NULL DEFAULT now(),
-- 表示可否
"表示" TEXT NOT NULL DEFAULT 'visible',
-- 一意&妥当性
CONSTRAINT uq_portal_fields_jp UNIQUE ("モデル技術名","フィールド技術名"),
CONSTRAINT ck_ttype_jp CHECK (
"データ型" IN ('char','text','html','integer','float','boolean',
'selection','many2one','one2many','many2many',
'date','datetime','monetary','binary')
),
CONSTRAINT ck_relation_required_jp CHECK (
("データ型" IN ('many2one','one2many','many2many') AND "関連モデル" IS NOT NULL)
OR ("データ型" NOT IN ('many2one','one2many','many2many'))
),
CONSTRAINT ck_visibility_jp CHECK ("表示" IN ('visible','invisible'))
);
-- よく使う項目に索引
CREATE INDEX idx_pf_model_jp ON portal_fields ("モデル技術名");
CREATE INDEX idx_pf_status_jp ON portal_fields ("実装状態");
CREATE INDEX idx_pf_groups_gin_jp ON portal_fields USING GIN ("権限グループ_xmlid配列");
CREATE INDEX idx_pf_label_gin_jp ON portal_fields USING GIN ("表示ラベル_i18n");
CREATE INDEX idx_pf_ui_gin_jp ON portal_fields USING GIN ("UI制御");
-- 更新日時の自動更新トリガ(任意)
CREATE OR REPLACE FUNCTION set_portal_fields_updated_at()
RETURNS trigger AS $$
BEGIN
NEW."更新日時" = now();
RETURN NEW;
END$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trg_portal_fields_updated_at ON portal_fields;
CREATE TRIGGER trg_portal_fields_updated_at
BEFORE UPDATE ON portal_fields
FOR EACH ROW EXECUTE FUNCTION set_portal_fields_updated_at();
✅ 推奨:英語カラムビュー(SELECT用)
DROP VIEW IF EXISTS portal_fields_en;
CREATE VIEW portal_fields_en AS
SELECT
"ID" AS id,
"モデル技術名" AS model,
"モデル物理名" AS model_table,
"フィールド技術名" AS field_name,
"データ型" AS ttype,
"関連モデル" AS relation_model,
"表示ラベル_i18n" AS label_i18n,
"ヘルプ_i18n" AS help_i18n,
"プレースホルダ_i18n" AS placeholder_i18n,
"単位_i18n" AS unit_i18n,
"備考_i18n" AS notes_i18n,
"値多言語フラグ" AS translate,
"選択肢" AS selection_items,
"既定値" AS default_value,
"ウィジェット" AS widget,
"UI制御" AS ui_control,
"権限グループ_xmlid配列" AS groups_xml_ids,
"由来" AS origin,
"実装状態" AS code_status,
"備考" AS notes,
"作成日時" AS created_at,
"更新日時" AS updated_at,
"表示" AS visibility
FROM portal_fields;
コメントを残す