Импорт данных из файлов в базу данных приложения
Формулировка задачи
Импортировать данные из нескольких файлов в базу данных приложения. Каждый файл содержит множество строк, и каждая строка должна быть помещена в отдельную строку таблицы базы данных. Во избежание отправки множества запросов для добавления данных требуется использовать операции множественного добавления.
Предположим, необходимо поместить в базу данных информацию из журналов событий. Журнал событий является текстовым файлом, в котором каждое событие описано в отдельной строке.
Предварительные требования
Создан проект с именем DataImport и псевдонимом MCHH. Настроена модель безопасности. Проект опубликован.
В разрабатываемом проекте создана модель данных, в которой описан класс Message с уникальным идентификатором guid и атрибутом Text типа text.
На основе класса сгенерированы экранные формы, в том числе MessagePage, отображающая таблицу с записями о событиях.
Для экранной формы MessagePage настроена маршрутизация со следующи ми параметрами:
- Путь:
/mchh; - Псевдоним:
mchh.
Рекомендуемое решение задачи
Рекомендуемый подход к решению описанной задачи включает следующие шаги:
-
Создание действия по добавлению записей в таблицу базы данных.
Выберите экранную форму MessagePage и создайте действие AddMessages типа GraphQL. В конструкторе GraphQL сконструируйте следующий GraphQL-запрос:
mutation($messages: [MCHH_MessageDataInput]) {
bulkadd_mchh_message(mchh_message: $messages) {
insertedIds
countObjectsModified
}
}Обратите внимание, что в GraphQL-запросе использована мутация множественного добавления bulkadd_mchh_message с параметром в виде массива записей, поскольку поставленная задача требует добавления множества записей в базу данных. Мутация множественного добавления является частью GraphQL-схемы проекта.
-
Изменение параметров источника данных getMessage.
В то время, когда экранная форма MessagePage открыта, для источника данных getMessage на вкладке События добавьте созданное действие AddMessages.
-
Добавление компонента FileUploader и настройка его свойств.
Выберите экранную форму MessagePage и добавьте компонент FileUploader, разместив его выше компонента DataGrid. Настройте следующие свойства FileUploader:
SingleButton={true}, что означает отображение компонента FileUploader в виде кнопки.Mode="Direct", что означает, что компонент не должен загружать файлы в файловое хранилище.
-
Описание обработчика событий нажатия кнопки в области компонента 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}
/>