Перейти к основному содержимому

Импорт данных из файлов в базу данных приложения

Формулировка задачи

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

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

Предварительные требования

Создан проект с именем DataImport и псевдонимом MCHH. Настроена модель безопасности. Проект опубликован.

В разрабатываемом проекте создана модель данных, в которой описан класс Message с уникальным идентификатором guid и атрибутом Text типа text.

На основе класса сгенерированы экранные формы, в том числе MessagePage, отображающая таблицу с записями о событиях.

Для экранной формы MessagePage настроена маршрутизация со следующими параметрами:

  • Путь: /mchh;
  • Псевдоним: mchh.

Рекомендуемое решение задачи

Рекомендуемый подход к решению описанной задачи включает следующие шаги:

  1. Создание действия по добавлению записей в таблицу базы данных.

    Выберите экранную форму MessagePage и создайте действие AddMessages типа GraphQL. В конструкторе GraphQL сконструируйте следующий GraphQL-запрос:

    mutation($messages: [MCHH_MessageDataInput]) {
    bulkadd_mchh_message(mchh_message: $messages) {
    insertedIds
    countObjectsModified
    }
    }

    Обратите внимание, что в GraphQL-запросе использована мутация множественного добавления bulkadd_mchh_message с параметром в виде массива записей, поскольку поставленная задача требует добавления множества записей в базу данных. Мутация множественного добавления является частью GraphQL-схемы проекта.

  2. Изменение параметров источника данных getMessage.

    В то время, когда экранная форма MessagePage открыта, для источника данных getMessage на вкладке События добавьте созданное действие AddMessages.

  3. Добавление компонента FileUploader и настройка его свойств.

    Выберите экранную форму MessagePage и добавьте компонент FileUploader, разместив его выше компонента DataGrid. Настройте следующие свойства FileUploader:

    • SingleButton={true}, что означает отображение компонента FileUploader в виде кнопки.
    • Mode="Direct", что означает, что компонент не должен загружать файлы в файловое хранилище.
  4. Описание обработчика событий нажатия кнопки в области компонента FileUploader.

    В код описания обработчика событий onFilesChange() добавьте следующий блок кода:

    OnFilesChange={async () => {
    // получение списка файлов, которые были выбраны по нажатию кнопки + (Плюс) в компоненте FileUploader
    const files = getEvent();
    // получения источника данных по имени
    const dataSourceTest = getDataSource("getMessage");
    const promises = Array.from(files).map((file) => {
    return new Promise((resolve, reject) => {
    const reader = new FileReader();
    // чтение данных из файла с помощью метода reader класса FileReader
    reader.onload = async (e) => {
    // получение одной записи исходя из условия: запись о каждом событии расположена в отдельной строке
    const messages = e.target.result.split("\r\n").map(msg => ({Text: msg}));
    await dataSourceTest.emit('addMessages', {messages});
    resolve();
    };
    reader.onerror = () => {
    reject("Ошибка при чтении файла");
    };
    reader.readAsText(file);
    });
    });
    // ожидание ответа об отправке всех файлов
    await Promise.all(promises);
    // обновление содержимого таблицы
    await dataSourceTest.load();
    }}

    Убедитесь, что код описания компонента FileUploader соответствует коду, представленному в следующем блоке.

       <FileUploader
    Text="Перетащите или"
    ChooseFileText="выберите файл"
    OnFilesChange={async () => {
    const files = getEvent();
    const dataSourceTest = getDataSource("getMessage");
    const promises = Array.from(files).map((file) => {
    return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = async (e) => {
    const messages = e.target.result.split("\r\n").map(msg => ({Text: msg}));
    await dataSourceTest.emit('addMessages', {messages});
    resolve();
    };
    reader.onerror = () => {
    reject("Ошибка при чтении файла");
    };
    reader.readAsText(file);
    });
    });
    await Promise.all(promises);
    await dataSourceTest.load();
    }}
    DownloadMode="Open"
    Multiple={true}
    Value-var="file1"
    OutputValue-var="file1"
    OutputState-var="__fileUploaderBusy__"
    WithDropzone={true}
    OnDropLabel="Отпустите для начала загрузки..."
    Mode="Direct"
    SingleButton={true}
    />