pgd
PGD — справочник по формату и CLI pgDesigner. Используй при работе с .pgd файлами.
- License 许可
- MIT
- 最近更新
- 2026-11-05
- Stars
- ★ 7
- Forks
- 1
01 前言 Front Matter
- name
- pgd
- paths
- **/*.pgd
- description
- PGD — справочник по формату и CLI pgDesigner. Используй при работе с .pgd файлами.
03 SKILL.md 正文
PGD — pgDesigner формат и CLI
.pgd — git-friendly XML-формат pgDesigner для схем PostgreSQL.
Источник правды — спецификация https://pgdesigner.io/docs/pgd-format и XSD pgd-format.xsd (в репозитории
pgdesigner — docs/pgd-format/). Скилл сверен с pgdesigner 0.0.6 (pgdesigner version); на другой версии
ловушки ниже перепроверь.
CLI: pgdesigner (не pgd).
Non-obvious правила редактирования
- Без числовых ID — объекты по имени; кросс-схемно через
schema.table <index>— на уровне<schema>, НЕ внутри<table>(частая ошибка при конверсии из PDD)- Порядок элементов в
<table>: column → pk → fk → unique → check → exclude → with → partition-by → partition - Порядок элементов в
<index>: ключи →<include>→<with>→<where>. Ключи —<column>и<expression>вперемешку, в порядке ключа индекса. Старый порядок (<where>перед<include>) pgdesigner читает, но XSD 0.0.6 его отвергает - Булевы — строки
"true"/"false"(не"0"/"1"как в PDD) - Сырой SQL — текстом элемента в CDATA:
<check>,<expression>и<where>индекса,<bound>партиции,<query>представления,<body>функции,<using>/<with-check>политики,<constraint>домена - Атрибутом, не текстом:
default="…"колонки и<generated expression="…">— XSD требует атрибут. Текст или CDATA внутри<generated>generateпревращает вGENERATED ALWAYS AS ();lintловит это как E033 nullabledefault"true"— для NOT NULL ставь явноnullable="false"comment="…"у<table>и<column>— этоCOMMENT ON- Действия FK указывай явно:
restrict,cascade,set-null,set-default,no action(с пробелом, остальные через дефис). Без атрибутаgenerateпишетNO ACTION, хотя XSD объявляетrestrict, иlintмолчит; W015 срабатывает только на явныйno action, аlint -fixменяет его наrestrict - Тип из не-public схемы — со схемой:
type="app.level", иначе PostgreSQL ищет его поsearch_path(W024) - Атрибуты на одной строке — иначе git-diff будет шумный
Корень
<?xml version="1.0" encoding="UTF-8"?>
<pgd version="1" pg-version="18" default-schema="public">
Иерархия
Все разделы необязательны; порядок — канонический:
<pgd>
├── <project>/<settings> <naming>, <defaults>, <lint ignore-rules>
├── <database> имя, кодировка, коллация
├── <roles> <tablespaces> <extensions>
├── <types> enum, composite, domain, range
├── <sequences>
├── <schema>
│ ├── <table>
│ │ └── column, pk, fk, unique, check, exclude, with,
│ │ partition-by, partition
│ └── <index> <-- на уровне schema!
├── <views> <functions> <triggers> <rules> <policies>
├── <comments> <grants>
└── <layouts> позиции, группы и цвета редактора
Канонические сниппеты
Enum — порядок <label> = порядок значений в PostgreSQL (см. ловушки diff):
<enum name="user_status" schema="public">
<label>active</label>
<label>inactive</label>
</enum>
FK (inline в <table>, в отличие от PDD):
<fk name="fk_orders_user" to-table="users" on-delete="cascade" on-update="restrict">
<column name="user_id" references="id"></column>
</fk>
Индекс по выражению / covering / partial / opclass:
<index name="idx_users_lower_email" table="users" using="btree">
<expression><![CDATA[lower(email)]]></expression>
<include><column name="name"></column></include>
<where><![CDATA[deleted_at IS NULL]]></where>
</index>
<index name="idx_users_name_trgm" table="users" using="gin">
<column name="name" opclass="gin_trgm_ops"></column>
</index>
<index name="idx_users_full_name_trgm" table="users" using="gin">
<expression opclass="gin_trgm_ops"><![CDATA[lower(full_name)]]></expression>
</index>
opclass, order и nulls у <expression> — как у <column>. Одно <expression> — один ключ: несколько ключей через запятую в одном выражении — W023.
IDENTITY и generated (stored="false" — VIRTUAL, PG18):
<column name="id" type="bigint" nullable="false">
<identity generated="always"></identity>
</column>
<column name="full_name" type="text">
<generated expression="first_name || ' ' || last_name" stored="true"></generated>
</column>
Партицирование — границу по timestamptz пиши со смещением, иначе она зависит от таймзоны сессии, которая накатывала миграцию (и см. ловушку сверки с базой):
<partition-by type="range"><column name="created_at"></column></partition-by>
<partition name="events_2024">
<bound>FOR VALUES FROM ('2024-01-01 00:00:00+00') TO ('2025-01-01 00:00:00+00')</bound>
</partition>
Полный синтаксис всех тегов и атрибутов: https://pgdesigner.io/docs/pgd-format.
Ловушки 0.0.6
diff → миграция
diff 0.0.6 выдаёт FK и комментарии новых таблиц, смену и снятие generated (SET EXPRESSION, DROP EXPRESSION),
пересоздание индекса при смене выражения, INCLUDE, NULLS NOT DISTINCT и WITH, ADD VALUE … AFTER для enum,
переименование индексов и ограничений. Миграцию всё равно проверяй: накати цепочку на пустую БД и сравни pg_dump -s
с базой из полного pgdesigner generate.
Рискованные шаги diff помечает в stderr и комментарием в SQL:
ENUM_ADD_VALUE— новое значение enum нельзя использовать до коммита транзакции. Если миграция тут же пишет это значение (UPDATE,DEFAULT), вынесиADD VALUEв отдельную миграцию, у/pgmigrator— в предыдущий файл или-NONTR.sql.TABLE_REWRITE— новое выражение stored generated-колонки переписывает таблицу под блокировкой.COLUMN_RECREATE(dangerous) — обычная колонка становится generated черезDROP COLUMN+ADD COLUMN: данные колонки пересчитываются, зависимые представления и FK блокируютDROP.TYPE_RECREATE(dangerous) — перестановка или удаление значения enum. SQL не выдаётся, только комментарий: PostgreSQL этого не умеет. Пиши руками (новый тип,ALTER COLUMN … TYPE … USING,DROP TYPEстарого) или не меняй порядок.
Сверка модели с живой базой
convertиз базы без-fullчитает таблицы и индексы, но не типы, представления, функции и триггеры —diffмодели с таким файлом предлагаетDROP TYPEдля каждого enum. Для сверки —convert -full.- Граница партиции без смещения (
'2024-01-01') база хранит в своей таймзоне ('2024-01-01 00:00:00+03'), иdiffпоказывает ложныйREATTACH_PARTITION. С явным смещением в модели ложной разницы нет. convert "postgres://…"пишет<dbname>.pgdи не перезаписывает существующий файл — задай-o. Пароль из DSN в сообщениях скрыт.
SQL → PGD маппинг
| SQL | PGD |
|---|---|
CREATE TABLE |
<table> в нужную <schema> |
ALTER TABLE ADD COLUMN |
<column> в <table> |
CREATE INDEX |
<index> в <schema> (не в <table>) |
ADD CONSTRAINT |
<pk>/<fk>/<unique>/<check> в <table> |
CREATE TYPE |
<enum>/<composite>/<domain>/<range> в <types> |
CREATE FUNCTION / PROCEDURE / AGGREGATE |
<function> в <functions>, kind="procedure"/"aggregate" |
COMMENT ON TABLE/COLUMN |
атрибут comment у <table>/<column> |
UNLOGGED, TABLESPACE, USING таблицы |
атрибуты unlogged, tablespace, using у <table> |
WITH (…), toast.* |
<with><param name="toast.autovacuum_enabled" value="false"></param></with> |
Отличия от PDD (MicroOLAP)
| Аспект | PDD | PGD |
|---|---|---|
| Идентификация | числовые ID | имена |
| Типы | коды (25, 1043) | имена (text, varchar) |
| NOT NULL | NotNull="1" |
nullable="false" |
| Индексы | внутри ENTITY | в <schema> |
| FK | секция REFERENCES | <fk> inline |
| Булевы | "0"/"1" |
"true"/"false" |
CLI pgdesigner
pgdesigner generate [-o schema.sql] schema.pgd # DDL
pgdesigner diff [-f json] [-o patch.sql] old.pgd new.pgd # ALTER (используется в /pgmigrator), см. ловушки
pgdesigner lint [-fix] [-s error] schema.pgd # 69 правил (E/W/I)
pgdesigner convert [-o project.pgd] schema.pdd|.sql|.dbs|.dm2
pgdesigner convert [-o project.pgd] [-schema s1,s2] -full "postgres://..." # см. сверку с базой
pgdesigner testdata [-seed 42 -rows 100] schema.pgd
pgdesigner merge base.pgd overlay.pgd
04 同仓库更多 Skills
zenrpc
Zenrpc — справочник по JSON-RPC 2.0 серверу для Go. Используй при создании и редактировании RPC-сервисов.
youtrack
YouTrack — задачи через REST API и pcurl. Используй для поиска issues, создания, обновления описаний, смены assignee/stage/приоритета, логирования времени и работы с комментариями.
topsrv
topsrv — метрики, алерты, CVE и HTTP-логи серверов проекта через публичный JSON-RPC API app.topsrv.io. Используй, когда нужна загрузка CPU, памяти или диска хоста, метрики PostgreSQL/nginx/angie агента topsrv (`topsrv_*`), какие алерты горят, уязвимые пакеты на серверах или кто (боты, сети, IP) нагружает сайт.
testing
Testing — используй всегда, когда пишешь или правишь Go-тесты (*_test.go), в том числе по сценариям Given/When/Then из spec: фреймворк как в соседних файлах, префикс TestDB, фабрики pkg/db/test, реальная БД без моков. Также при настройке TestMain/test-short и когда тесты падают в gate, но проходят локально.
solve
Solve — полный цикл решения задачи из YouTrack: preflight → анализ → план → реализация → ревью → коммит. Используй при любой YouTrack-задаче (`/solve PLF-819`); флаг `--fast` сокращает HITL для тривиальных багфиксов.
skills-check
Skills Check — smoke-тесты интеграций из project-index.md. Используй для проверки что pcurl-профили и URL всех data-source скиллов ещё живы.