Первинне завантаження даних реєстру (initial load)

🌐 Цей документ доступний українською та англійською мовами. Використовуйте перемикач у правому верхньому куті, щоб змінити версію.

Для первинного завантаження даних використовується БД-процедура PL/pgSQL.

Перед виконанням процедури первинного завантаження даних, переконайтеся, що виконано передумови, описані в секції Підготовка даних до міграції.

1. Специфікація PL/pgSQL процедури для БД Платформи

Процедура для завантаження даних
CREATE OR REPLACE PROCEDURE p_load_table_from_csv(
p_table_name text
, p_file_name text
, p_table_columns text[]
, p_target_table_columns text[] DEFAULT NULL::text[]
);
Опис параметрів:
  • p_table_name - назва цільової таблиці;

  • p_file_name - повний шлях до файлу з даними для завантаження у форматі CSV;

  • p_table_columns - масив назв полів у файлі даних (перший рядок CSV-файлу);

  • p_target_table_columns - масив полів цільової таблиці (відсутній, якщо перелік полів збігається із полями в CSV-файлі).

    Значення елементів параметра p_target_table_columns може набувати різних форматів:

    • <col_name> — поле в цільовій таблиці отримує значення відповідного (за назвою) поля в CSV-файлі;

    • <col_name>::<some_calculation_based_on_source_cols> — поле отримує значення — результат виразу

      Детальніше — див. підрозділ Складний сценарій 1 у прикладах виклику.
    • <col_name>::ref(lookup_col:<lookup_col_name>, ref_table:<ref_table_name>, ref_col:<ref_col_name>, ref_id:<ref_id_col_name>) — для даного формату "під капотом" виконується наступний SQL-запит, що реалізовує пошук id по таблиці довідника:

      SELECT <ref_id> INTO <col_name> FROM <ref_table> WHERE <ref_col> = <lookup_col>;

      Такий запит застосовується у випадку, коли поле містить зовнішній ключ (англ. — foreign key) посилання на довідник, а значення для завантаження у CSV-файлі представлене не ідентифікатором, а описовим полем, проте значення цього поля мають бути унікальними.

      Детальніше — див. підрозділ Cкладний сценарій 2 у прикладах виклику.
    • <col_name>::ref_array(lookup_col:<lookup_col_name>, ref_table:<ref_table_name>, ref_col:<ref_col_name>, ref_id:<ref_id_col_name>, delim:<delimeter_character>) — цей формат відмінний від попереднього лише тим, що поле <lookup_col_name> у CSV-файлі містить масив описових значень. В результаті повертатиметься масив відповідних id.

2. Приклади виклику процедури

2.1. Простий сценарій

CALL p_load_table_from_csv('research',
'D:\PostgreSQL\csv\uuid\01-Typy_doslidgen_uuid.csv', array
['uuid','research_type'], array['research_type']);

2.2. Складний сценарій 1

CALL p_load_table_from_csv('koatuu','${dataLoadPath}03-KOATUU_simple.csv'
, array['code','category','name']
, array['code','category','name'
,'level1::substring(code,1,2)||''00000000'''
,'level2::substring(code,1,5)||''00000'''
,'type::CASE WHEN code ~ ''[0-9]{2}0{8}'' AND code !~ ''(80|85)0{8}'' THEN ''О''
            WHEN code ~ ''[0-9]{2}2[0-9]{2}0{5}'' AND code !~ ''[0-9]{2}20{7}'' THEN ''Р''
            WHEN coalesce(category, ''Р'') != ''Р''
            OR code IN (SELECT DISTINCT substring(code,1,5)||''00000'' FROM koatuu_csv k2 WHERE category = ''Р'') AND category IS NULL
            OR code ~ ''(80|85)0{8}'' THEN ''НП''
            ELSE NULL END']
);

2.3. Складний сценарій 2

CALL p_load_table_from_csv('staff','D:\PostgreSQL\csv\staff.csv'

,array['uuid','laboratory','staff_status','researches','full_name','hygienist_flag','full_time_flag','salary','fixed_term_contract_flag','contract_end_date','specialization_date','specialization_end_date','dismissal_flag','dismissal_date']
  ,array['laboratory_id::ref(lookup_col:laboratory,ref_table:laboratory,ref_col:name,ref_id:laboratory_id)'
        ,'staff_status_id::ref(lookup_col:staff_status,ref_table:staff_status,ref_col:name,ref_id:staff_status_id)'
        ,'researches::ref_array(lookup_col:researches,ref_table:research,ref_col:research_type,ref_id:research_id,delim:#)'
        ,'full_name','hygienist_flag','full_time_flag','salary','fixed_term_contract_flag','contract_end_date','specialization_date','specialization_end_date','dismissal_flag','dismissal_date']
     );

3. Завантаження даних до БД

Для завантаження даних в БД використовуємо стандартну функціональність liquibase.

Приклад XML-шаблону для завантаження даних
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.2.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext xsd/dbchangelog-ext.xsd">

    <property  name="dataLoadPath"  value="D:\PostgreSQL\csv\"/>

    <changeSet author="registry owner" id="load data to dictionaries">
        <sql dbms="postgresql" endDelimiter=";" splitStatements="true" stripComments="true">
            CALL p_load_table_from_csv('research','${dataLoadPath}01-Typy doslidgen.csv', array['code','research_type'], array['research_type']);
            CALL p_load_table_from_csv('refusal_reason','${dataLoadPath}02-Prichiny vidmov.csv', array['code','document_type','name','constant_code'], array['document_type','name','constant_code']);
            CALL p_load_table_from_csv('kopfg','${dataLoadPath}05-kopfg.csv', array['code','name']);
            CALL p_load_table_from_csv('solution_type','${dataLoadPath}06-Typy rishen.csv', array['id','name','constant_code'], array['name','constant_code']);
            CALL p_load_table_from_csv('factor','${dataLoadPath}14-Himichni_factory_OBRV.csv', array['code','name','col3','col4'], array['name','factor_type::''Хімічний: ОБРВ''']);
            CALL p_load_table_from_csv('factor','${dataLoadPath}15-Himichni factory dovilni.csv', array['code','name'], array['name','factor_type::''Хімічний: довільні''']);
        </sql>
  </changeSet>

</databaseChangeLog>
За детальною інформацією щодо створення фізичної моделі даних реєстру за допомогою інструмента Liquibase зверніться до розділу "Створення фізичної моделі даних реєстру" цього документа.

4. Вимоги до файлів для завантаження до БД

Файли, що використовуватимуться для завантаження даних до БД, повинні мати чітку структуру.

Вимоги до файлів для автоматичного завантаження в БД:
  • тільки СSV-формат;

  • назва файлу — латиницею;

  • кодування — UTF8;

  • перший рядок містить назви полів;

  • починаючи із другого рядка містяться значення полів (структура відповідає назвам полів із першого рядка);

  • значення полів одного рядка файлу повністю визначають значення полів, необхідних для створення запису в базі даних;

  • розділювач значень полів: , (кома) або ; (крапка з комою);

  • відсутність значення (NULL) передається відсутнім значенням, наприклад, …​значення 1,,значення 3…​, тобто відсутнє значення пропускається між двома комами, а не позначається пробілом);

  • наявність унікальності за одним бізнес-полем (наприклад, поле Назва) — для довідників;

  • для позначення масивів описових значень використовуються фігурні дужки {, }.

5. Рекомендації для завантаження великої кількості даних

Для завантаження великої кількості даних (понад 1 млн рядків) рекомендується тимчасова зміна конфігурації БД — у файлі з налаштуваннями PostgreSQL postgresql.conf встановити наступні значення для часу очікування підключень між реплікою та основною (master) БД:

wal_sender_timeout = 900s
wal_receiver_timeout = 900s