Расширяемость
Создание расширений
16
Авторские права
© Postgres Professional, 2017–2024
Авторы: Егор Рогов, Павел Лузанов, Илья Баштанов, Игорь Гнатюк
Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации,
демонстрации) разрешается без ограничений. Коммерческое
использование возможно только с письменного разрешения компании
Postgres Professional. Запрещается внесение изменений в материалы
курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу:
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за
любые повреждения и убытки, включая потерю дохода, нанесенные
прямым или непрямым, специальным или случайным использованием
материалов курса. Компания Postgres Professional не предоставляет
каких-либо гарантий на материалы курса. Материалы курса
предоставляются на основе принципа «как есть» и компания Postgres
Professional не обязана предоставлять сопровождение, поддержку,
обновления, расширения и изменения.
2
Темы
Расширения в PostgreSQL
Создание расширений
Версии расширений и обновление
Особенности работы утилиты pg_dump
3
Расширяемость PostgreSQL
Возможности
функции и языки программирования
типы данных, операторы, методы доступа
обертки сторонних данных (FDW)
Механизмы
изменяемый системный каталог
API для подключения внешних обработчиков
загрузка и выполнение пользовательского кода
Расширяемость — важнейшая черта PostgreSQL — это возможность
подключать «на лету» новый функционал без изменения кода сервера.
Таким образом можно добавлять языки программирования
и разрабатывать на них функции, определять новые типы данных
и операторы для работы с ними, создавать новые методы доступа для
типов данных, разрабатывать обертки сторонних данных для
подключения к внешним источникам.
Для того чтобы это было возможным, системный каталог PostgreSQL
хранит большое количество информации об объектах БД. Эта
информация не зашита жестко в код сервера. Пользователи могут
изменять содержимое таблиц системного каталога, тем самым
добавляя новые объекты и связанный с ними функционал.
Кроме того, в исходном коде PostgreSQL встроено большое количество
хуков и различных API для подключения пользовательских функций.
Это дает возможность разрабатывать такие расширения как
pg_stat_statements, auto_explain, pldebugger и многие, многие другие.
Завершает картину возможность загружать в серверные процессы
пользовательский код. Например, можно написать разделяемую
библиотеку и подключать ее по ходу работы.
В качестве предостережения следует отметить, что выполнение
процессами сервера неправильно написанного пользовательского кода
может привести к катастрофическим последствиям. Следует доверять
только проверенному коду из надежных источников.
4
Расширения
Группа взаимосвязанных объектов БД
установка всех объектов одной командой
невозможность удалить отдельный объект
сохранение связи при выгрузке с помощью pg_dump
инструменты для перехода на новую версию
Источники
в составе дистрибутива (contrib)
внешние расширения
возможность создания собственных расширений
Бывают ситуации, когда несколько объектов базы данных логически
связаны между собой. Например, несколько типов данных, функции
и операторы для работы с ними, классы операторов. Такую связь
можно сделать явной с помощью механизма расширений.
Это облегчает управление объектами:
все объекты устанавливаются одной командой;
невозможно удалить отдельный объект — расширение можно
удалить только полностью;
связь между объектами сохраняется и при создании резервной копии
с помощью утилиты pg_dump;
есть инструменты для управления версиями расширений.
В состав PostgreSQL входит значительное количество полезных
расширений, частью из которых мы уже пользовались.
Другой источник — PostgreSQL Extension Network (PGXN) — сеть
расширений по аналогии с CPAN для Perl: https://pgxn.org/
Расширения могут распространяться и другими способами, в том числе
через пакетные репозитории дистрибутивов ОС.
В этой теме мы рассмотрим, как создавать собственные расширения.
5
Создание расширения
1.0
CREATE EXTENSION
VERSION '1.0'
имя--1.0.sql
имя.control
скрипт
создания
параметры
DROP EXTENSION
Расширение устанавливается в базу данных командой CREATE
EXTENSION. При этом должны существовать два файла:
управляющий файл «имя.control» с параметрами расширения;
скрипт создания объектов расширения «имя--версия.sql».
Версия традиционно имеет вид «1.0», «1.1» и т. д., но это не
обязательно: ее имя может состоять из любых символов (но не должно
содержать «--» и начинаться или заканчиваться на «-»).
Обычно версию не указывают в команде CREATE EXTENSION,
поскольку текущая актуальная версия записана в управляющем файле
(параметр default_version) и используется по умолчанию.
Другие параметры расширения указывают зависимости от других
расширений (requires), возможность перемещения объектов
расширения между схемами (relocatable), возможность установки
только суперпользователем (superuser) и др.
Расширение удаляется командой DROP EXTENSION. Скрипт для
удаления объектов писать не нужно.
7
Обновление расширения
1.0 1.1
ALTER EXTENSION
UPDATE TO '1.1'
1.2
ALTER EXTENSION
UPDATE TO '1.2'
CREATE EXTENSION
VERSION '1.0'
имя--1.0.sql
имя.control
имя--1.0--1.1.sql имя--1.1--1.2.sql
скрипт
создания
скрипт
обновления
параметры
имя--1.2.control
дополнит.
параметры
Обновление версии расширения выполняется командой ALTER
EXTENSION UPDATE. При этом должен существовать скрипт
обновления «имя--старая-версия--новая-версия.sql», содержащий
необходимые для обновления команды.
Также необходимо изменить управляющий файл «имя.control», обновив
актуальную версию и, возможно, другие параметры.
При необходимости может существовать и отдельный управляющий
файл, привязанный к версии. Например, если в версии 1.2 появилась
зависимость от другого расширения, то эту зависимость неправильно
указывать в основном управляющем файле. Параметры, указанные
в дополнительном управляющем файле, более приоритетны, чем
параметры основного управляющего файла.
В примере, приведенном на слайде, имеются скрипты обновления
1.0→1.1 и 1.1→1.2. Можно создать и скрипт 1.0→1.2, но, как правило,
это не требуется: механизм расширений сам берет на себя выбор пути
с учетом доступных переходов между версиями. Например, если
установлена версия 1.0, то ее можно обновить сразу до 1.2: сначала
автоматически применится скрипт 1.0→1.1, а затем 1.1→1.2.
Как и при создании, при обновлении номер версии обычно не
указывают — в этом случае обновление происходит до последней
актуальной версии, записанной в основном управляющем файле.
9
Итоги
Расширения — упаковка взаимосвязанных объектов БД,
предназначенных для решения какой-либо задачи
Расширения упрощают использование функционала
Имеются средства для разработки собственных расширений
10
Практика
1. Создайте расширение bookfmt, содержащее все необходимое
для работы с типом данных для формата изданий.
Установите расширение, чтобы объединить имеющиеся
в базе данных разрозненные объекты.
2. Воспользуйтесь стандартным расширением isn для того
чтобы проверить корректность кодов ISBN у имеющихся
в магазине книг.
1. Объекты базы данных, относящиеся к книжному формату — тип
данных book_format, приведение типов, функции, операторы и класс
операторов — мы создавали в темах «Пользовательские типы данных»
и «Классы операторов».
Если создать расширение так, как это показывалось в демонстрации,
то для его установки придется удалить из базы существующие объекты.
Что, конечно, нежелательно для работающей системы.
Поэтому сначала создайте и установите пустое расширение, а затем
напишите скрипт для его обновления, добавляющий к расширению уже
имеющиеся в базе данных объекты с помощью команды ALTER
EXTENSION ADD ....
2. В достаточно старых книгах используется 10-значный код ISBN.
С 2007 года для совместимости со штрихкодами используют 13-
значный код ISBN (первые три цифры всегда равны 978).
Код имеет формат: 978 страна изд-во издание контрольная_цифра.
Между группами цифр обычно ставятся дефисы, но это незначащий
символ. Контрольная цифра вычисляется по специальным правилам.
В расширении isn имеются функции isbn(text) для 10-значного кода
и isbn13(text) для 13-значного. Если контрольная цифра неверна,
функции вызывают ошибку.
11
Практика+
1. Создайте расширение с функцией для подготовки текста
к публикации. Функция должна применить к текстовому
параметру последовательность правил, выполняющих
замену по регулярному выражению, и вернуть результат.
Правила должны храниться в таблице и применяться
в порядке их вставки. К предопределенным правилам
пользователь может добавлять собственные.
Работа функции не должна зависеть от настройки пути
поиска, но должна позволять выбрать схему при установке.
2. Установите расширение в схему typo, добавьте в таблицу
пользовательское правило. Корректно ли выгружает копию
базы данных утилита pg_dump? Проверьте возможность
добавить правило после восстановления из резервной копии.
1. В качестве предопределенных правил используйте, например:
(^|\s)\"(\S) \1«\2
(\S)\"(\s|$) → \1»\2
(^|\s)-(\s|$) → \1—\2
Эти правила заменяют (не всегда корректно) обычные символы на
кавычки-елочки и тире:
- Буквы "р" нет, - сказал я. Буквы «р» нет, — сказал я.
Чтобы обеспечить независимость от пути поиска, расширение придется
сделать непереносимым. Укажите соответствующий параметр
в управляющем файла, а в теле функции используйте макрос
@extschema@ для указания схемы, в которой находится таблица
правил. Этот макрос будет заменен на выбранную схему при установке.
2. Чтобы утилита pg_dump правильно выгружала пользовательские
правила, используйте функцию pg_extension_config_dump и для самой
таблицы, и для последовательности, созданной для первичного ключа.
При вызове pg_dump можно указать ключи --clean и --create, чтобы
копия включала в себя команды для удаления и создания базы данных.