Материалы / Разборы pgtools / Как изменить тип поля PostgreSQL, если на него ссылаются представления
Разбор pgtools

Как изменить тип поля PostgreSQL, если на него ссылаются представления

Инструмент зависимых объектов в pgtools помогает удалить и пересоздать views в правильном порядке при изменении таблиц PostgreSQL.

При сопровождении базы данных PostgreSQL часто возникает простая на первый взгляд задача: изменить тип поля, переименовать колонку, удалить устаревшее поле или выполнить другой DDL над таблицей.

Например:

alter table test.employees
alter column employee_id type bigint
using employee_id::bigint;

Но если от этой таблицы зависят представления, PostgreSQL может не дать выполнить такую операцию:

ERROR: cannot alter type of a column used by a view or rule

Такая ошибка особенно неприятна в больших базах данных, где от одной таблицы могут зависеть десятки или сотни VIEW. В моей рабочей задаче нужно было изменить типы полей в таблицах, от которых зависело более 200 представлений. Вручную сохранять их код, разбирать порядок зависимостей, удалять и затем пересоздавать объекты - долго, рискованно и неудобно.

Для таких случаев в pgtools был создан инструмент работы с зависимыми объектами.

Когда полезен инструмент зависимых объектов

Инструмент пригодится, если вы работаете с PostgreSQL и сталкиваетесь с такими задачами:

  • нужно изменить тип колонки, но PostgreSQL пишет cannot alter type of a column used by a view or rule;
  • нужно переименовать поле таблицы, от которого зависят представления;
  • нужно удалить или изменить колонку, которая используется во VIEW;
  • нужно выполнить DDL над таблицей, но сначала безопасно удалить зависимые объекты;
  • нужно сохранить исходный SQL-код всех зависимых представлений перед изменениями;
  • нужно пересоздать удаленные VIEW в правильном порядке с учетом иерархии зависимостей;
  • нужно заранее поправить SQL-код представлений перед их повторным созданием.

Без такого инструмента стандартный процесс обычно выглядит так: найти все зависимые объекты, получить их DDL, понять порядок зависимостей, сохранить код, удалить все эти VIEW, изменить таблицу, затем создать все представления обратно. Если зависимостей много, это легко превращается в отдельную сложную миграцию.

В pgtools этот сценарий собран в отдельный визуальный инструмент.

Как открыть зависимости таблицы

После подключения к базе данных откройте дерево объектов, найдите нужную таблицу, нажмите по ней правой кнопкой мыши и выберите пункт «Зависимости».

<a class=“lightbox” href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_menu.png” data-dark-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_menu.png” data-light-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_menu.png” data-pswp-width=“1916” data-pswp-height=“1030”

<img src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_menu.png” data-dark-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_menu.png” data-light-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_menu.png” alt=“Вызов меню для просмотра зависимых объектов в pgtools” loading=“lazy”

На примере выше таблица test.employees используется в нескольких представлениях. При попытке изменить тип поля PostgreSQL возвращает ошибку, потому что поле используется во VIEW.

Через контекстное меню pgtools можно сразу открыть список зависимых объектов и перейти к подготовке изменений.

Просмотр дерева зависимостей

После открытия инструмента pgtools строит дерево зависимых объектов. В нем видно, какие представления зависят от выбранной таблицы и как они связаны между собой.

Слева отображается иерархия объектов, справа - SQL-код выбранного представления. По каждому объекту можно посмотреть исходный код и при необходимости внести изменения.

Это удобно, если перед изменением таблицы нужно заранее подготовить зависимые VIEW.

Например, если вы переименовываете поле в исходной таблице, можно сразу заменить старое имя поля в SQL-коде представлений. После повторного создания объекты будут созданы уже с учетом этих правок.

На этой же вкладке можно сохранить как оригинальный код представлений, так и итоговый код с изменениями.

<a class=“lightbox” href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_obj_tree.png” data-dark-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_obj_tree.png” data-light-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_obj_tree.png” data-pswp-width=“1916” data-pswp-height=“1030”

<img src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_obj_tree.png” data-dark-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_obj_tree.png” data-light-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_obj_tree.png” alt=“Дерево зависимых объектов в pgtools” loading=“lazy”

Безопасное удаление зависимых объектов

Когда изменения подготовлены, можно нажать красную кнопку «Удалить все объекты в БД».

Если исходный код зависимых представлений еще не был сохранен, pgtools предложит сохранить его в файл. Это дополнительная страховка перед удалением объектов из базы данных.

После подтверждения инструмент удаляет зависимые объекты и показывает результат в дереве. Справа отображается журнал выполнения команд.

Такой подход помогает не потерять DDL объектов и видеть, какие действия уже выполнены.

<a class=“lightbox” href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_drop.png” data-dark-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_drop.png” data-light-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_drop.png” data-pswp-width=“1916” data-pswp-height=“1030”

<img src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_drop.png” data-dark-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_drop.png” data-light-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_drop.png” alt=“Удаление зависимых объектов в pgtools” loading=“lazy”

Изменение таблицы

После удаления зависимых представлений можно выполнить нужный DDL над таблицей.

Например, изменить тип поля:

alter table test.employees
alter column employee_id type bigint
using employee_id::bigint;

Или переименовать колонку:

alter table test.employees
rename column employee_id to id;

Или выполнить другую структурную доработку таблицы, которая раньше блокировалась зависимыми объектами.

Повторное создание объектов

После изменения таблицы нажмите зеленую кнопку «Создать все объекты в БД».

pgtools пересоздаст удаленные объекты с учетом иерархии зависимостей. Это важно, потому что одно представление может зависеть не только от таблицы, но и от другого представления. Если создавать такие объекты в неправильном порядке, PostgreSQL вернет ошибку.

При повторном создании используются уже подготовленные версии SQL-кода. Поэтому, если вы заранее изменили код представлений, например заменили имя поля, в базу будут созданы обновленные VIEW.

<a class=“lightbox” href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_recreate.png” data-dark-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_recreate.png” data-light-href=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_recreate.png” data-pswp-width=“1916” data-pswp-height=“1030”

<img src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_recreate.png” data-dark-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/dark/screen_depend_recreate.png” data-light-src=“/images/materials/pgtools/postgresql-cannot-alter-column-used-by-view/light/screen_depend_recreate.png” alt=“Повторное создание зависимых объектов в pgtools” loading=“lazy”

Что делает инструмент

Инструмент зависимых объектов в pgtools помогает выполнить полный цикл работы с зависимостями:

  • найти объекты, которые зависят от выбранной таблицы;
  • построить дерево зависимостей;
  • показать SQL-код каждого зависимого объекта;
  • дать возможность изменить код представлений до удаления;
  • сохранить исходный или измененный DDL в файл;
  • удалить зависимые объекты из базы;
  • позволить выполнить DDL над исходной таблицей;
  • пересоздать объекты в правильном порядке.

Чем это отличается от ручной работы

Вручную подобную задачу можно решить через системные каталоги PostgreSQL, pg_depend, pg_rewrite, pg_class, pg_namespace и функции получения DDL. Но на практике это требует внимательности и занимает много времени.

Особенно сложно становится, когда:

  • зависимых представлений много;
  • представления зависят друг от друга;
  • нужно менять SQL-код части объектов;
  • важно не потерять исходный DDL;
  • нужно видеть, какие объекты уже удалены или созданы;
  • нужно быстро выполнить изменение в рабочей базе без хаоса в скриптах.

pgtools не просто показывает список зависимостей, а помогает пройти весь процесс изменения таблицы: от анализа зависимых объектов до их повторного создания.

Типовой сценарий использования

Типовой сценарий выглядит так:

-- Было:
alter table test.employees
alter column employee_id type bigint
using employee_id::bigint;
-- PostgreSQL вернул ошибку:
-- cannot alter type of a column used by a view or rule

Дальше в pgtools:

  • открываем таблицу в дереве объектов;
  • выбираем пункт «Зависимости»;
  • проверяем список зависимых VIEW;
  • при необходимости правим SQL-код представлений;
  • сохраняем DDL зависимых объектов;
  • удаляем зависимые объекты;
  • выполняем DDL над таблицей;
  • создаем все объекты обратно.

В результате изменение таблицы выполняется контролируемо, а зависимые представления возвращаются в базу уже в актуальном виде.

Итог

Инструмент зависимых объектов в pgtools создан для практических задач сопровождения PostgreSQL-баз, где изменения таблиц часто упираются в зависимые представления.

Он особенно полезен при рефакторинге структуры базы данных: изменении типов полей, переименовании колонок, изменении DDL таблиц и подготовке миграций. Вместо ручного поиска, сохранения, удаления и пересоздания VIEW можно работать с зависимостями в одном окне и видеть весь процесс выполнения.

Если вы сталкивались с ошибкой PostgreSQL cannot alter type of a column used by a view or rule, этот инструмент помогает быстро и безопасно пройти весь путь от проблемного DDL до обновленной структуры базы данных.