Миграция перекрестных ссылок на базы данных
Как известно, PostgreSQL, в отличие от Sybase ASE и Microsoft SQL Server, не поддерживает нативные межбазовые (cross-database) ссылки.
При планировании миграции существует несколько возможных подходов к обработке баз данных, на которые ссылаются через границы БД:
- миграция исходных баз данных как отдельных баз в одном экземпляре PostgreSQL или на разных инстансах
- объединение нескольких баз данных в одну базу PostgreSQL с сохранением разделения на уровне схем
- объединение нескольких баз данных в одну базу PostgreSQL и одну схему
- временное оставление одной или нескольких баз данных в Sybase с обработкой межбазовых зависимостей на уровне приложения или интеграционного слоя
Все эти подходы могут быть реализованы или адаптированы в зависимости от конкретных требований и ограничений. Выбор стратегии в значительной степени определяется архитектурными, эксплуатационными и бизнес-факторами.
На практике чаще всего используются подходы №2 и №3.
Идентификация и отчётность по кросс-базовым ссылкам
Во время этапов оценки или конвертации Инструменты Конвертум обрабатывают межбазовые ссылки следующим образом:
- инструмент Конвертум Сканер не выполняет явного сбора или отчётности по межбазовым ссылкам
- Конвертум Мастер конвертирует такие ссылки неявно и не выделяет их в отдельную категорию
Уровень автоматической конвертации
Отчёт Конвертум Сканер не присваивает явного ранжирования межбазовым зависимостям. Однако на практике такие зависимости относятся к высокому уровню сложности.
При выборе стратегии объединения баз данных эти зависимости обычно обеспечивают примерно 50% автоматической конвертации, при этом оставшаяся часть требует ручной доработки.
Рекомендации по работе с межбазовыми зависимостями в PostgreSQL
Независимо от выбранного подхода миграции, настоятельно рекомендуется проверять весь код, сгенерированный инструментом. Инструкции по проверке приведены здесь.
В некоторых случаях кросс-базовые ссылки могут быть распознаны некорректно. В таких ситуациях может потребоваться ручная корректировка или настройка инструмента.
Также важно учитывать, что инструмент не всегда может автоматически получить определение объекта, если он находится в другой базе данных. В результате могут возникать проблемы, такие как несовместимость типов данных или отсутствие параметров типа REFCURSOR OUT в вызовах процедур.
Эти проблемы должны быть выявлены на этапе валидации и устранены с помощью целенаправленных ручных исправлений.
Необходимые настройки и функции
Миграция межбазовых ссылок обычно требует настройки определённого набора параметров конвертации. Эти параметры помогают адаптировать код под выбранную архитектуру PostgreSQL и минимизировать проблемы, связанные с межбазовыми зависимостями:
CONVERT_DATABASE_TO_SCHEMA
CONVERT_DBLINK_TO_SCHEMA
подробную информацию про эти опции вы можете найти в документации о Разделе DDL А также будет полезным использовать маппинг схем: [Настройки маппинга схем] (https://www.convertum.ru/docs/knowledge-base/database-migration/tips-and-tricks/schema-mapping)
В любом случае, процесс включает создание Директории Проекта и ODBC-подключения для каждой мигрируемой базы данных.
Предположим, что у нас есть две базы данных: db1_db и db2_db. В базе данных db2_db существует процедура, которая ссылается на db1_db. Для их конвертации необходимо использовать два разных проекта с отдельными каталогами проектов.
Каждый проект должен использовать собственное ODBC-подключение, указывающее на соответствующую исходную базу данных.
Оба проекта используют одинаковые настройки целевой базы данных, поэтому импорт выполняется в одну и ту же целевую базу данных.
Для обоих каталогов проектов необходимо задать следующие параметры в секции [DDL]:
EMPTY_SCHEMA = No
OUTSCHEMA = <имя исходной базы данных>
В результате, объекты из БД №1 будут помещены в схему db1_db, а объекты из БД №2 — в схему db2_db.
Дополнительно необходимо настроить следующие параметры в секции [DDL]:
CONVERT_DATABASE_TO_SCHEMA = Yes
CONVERT_DBLINK_TO_SCHEMA = Yes
Результат конвертации:
DB #1 DB #2
create or replace procedure db1_db.proc1(INOUT SWV_RefCur refcursor default null, INOUT SWV_RefCur2 refcursor default null)
LANGUAGE plpgsql
AS $$
DECLARE
v_t VARCHAR(100);
BEGIN
open SWV_RefCur for
select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1 where 1 = 1;
open SWV_RefCur2 for
select CONCAT(COALESCE(v_t,''),COALESCE(p,'')) from db1_db.tab1 where 1 = 1;
END; $$;
create or replace FUNCTION db2_db.proc2()
RETURNS TABLE
(
col VARCHAR
) LANGUAGE plpgsql
AS $$
DECLARE
v_t VARCHAR(100);
BEGIN
CALL db1_db.proc1();
return query
select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1
where id = cast('1' as INTEGER);
END; $$;
Как показано выше:
Процедура proc2 считается имеющей только один результирующий набор и была преобразована в функцию с RETURNS TABLE. Ссылки (references) указывают на корректные схемы. Тип данных столбца id был правильно определён как INTEGER, и в предложении WHERE было добавлено приведение типа (CAST) для корректной обработки различий в типах.
Однако вызов процедуры db1_db.proc1 в БД №2 не содержит параметров INOUT REFCURSOR.
Это происходит потому, что из первой базы данных невозможно определить, требуются ли эти REFCURSOR.
Для корректного определения и преобразования необходимо иметь доступ к полному определению процедуры из БД №1 в БД №2, чего наш инструмент не поддерживает.
Подобные случаи требуют ручной корректировки.
Ниже приведён вручную скорректированный вариант proc2:
create or replace procedure db2_db.proc2(
INOUT SWV_RefCur refcursor default null,
INOUT SWV_RefCur2 refcursor default null,
INOUT SWV_RefCur3 refcursor default null
) LANGUAGE plpgsql
AS $$
DECLARE
v_t VARCHAR(100);
BEGIN
CALL db1_db.proc1(SWV_RefCur, SWV_RefCur2);
open SWV_RefCur3 for
select CONCAT(COALESCE(p,''),COALESCE(v_t,'')) from db1_db.tab1
where id = cast('1' as INTEGER);
END; $$;

