Пошаговые инструкции Для начинающих 13 мин

Data Tables в n8n: как сохранить результаты и прочитать их позже

Создайте таблицу результатов заказов: Upsert по ID, повторный запуск, фильтр ready и чтение после перезапуска. Два готовых workflow и 14 шагов.

автоматизация n8n Data Tables

OUTPUT узла показывает результат конкретного выполнения. Если следующая схема должна прочитать его позже, данные нужно сохранить отдельно. В n8n для этого есть Data Tables — внутренние таблицы. Создадим таблицу результатов заказов, запишем три строки через Upsert и прочитаем их другим workflow, в том числе после перезапуска n8n.

Результат инструкции

В таблице ezgpt_order_results будет по одной строке последнего результата для заказов O1, O2 и O3. У O1 сумма 150000 копеек, у O2 — допустимый ноль, у ошибочного O3 — needs_review и причины проверки, а сумма пустая. Повторный последовательный запуск обновит строки по order_id, а не добавит ещё три.

Это хранилище текущих результатов, не история всех событий и не защита от одновременных записей. AI-модели, оплаты и отправки здесь нет. Статус ready означает прохождение наших учебных правил, а не разрешение автоматически списывать деньги или отправлять заказ клиенту.

Что понадобится

  • Работающий n8n с доступным разделом Data tables. Сценарий проверен на n8n 2.42.4.
  • Права создавать таблицы и workflows в одном своём проекте. В учебной таблице не используйте настоящие данные клиентов.
  • Для локальной установки — сохраняемый том n8n. Перезапуск без сохранённого хранилища не доказывает долговечность данных.

Установка n8n через Docker с сохраняемым томом

Шаг 1. Создайте пустую Data Table

Откройте свой проект n8n и вкладку Data tables. Выберите Create Data table, затем создание From scratch. Назовите таблицу ровно ezgpt_order_results. Не создавайте её в другом проекте: оба учебных workflows должны работать с этой же таблицей.

Если Data tables отсутствует, проверьте версию и доступность функции у администратора. Не заменяйте её обычной переменной или закреплённым OUTPUT: это другой способ хранения и не повторит наш пример.

Шаг 2. Добавьте пять колонок

В созданной таблице добавьте колонки с именами и типами ниже. Для string используйте текстовый тип интерфейса, для number — числовой. Не переводите имена колонок на русский и не добавляйте в них пробелы.

Колонка Тип Что хранит
order_id string ID заказа: O1, O2, O3
status string ready или needs_review
amount_minor number Копейки; null при ошибке
errors_text string Причины проверки или пустой текст
validation_version string Учебная метка v1

Системные id, createdAt и updatedAt n8n добавляет сам; повторно создавать их не нужно. order_id — наш идентификатор заказа, id — идентификатор строки таблицы. Это разные поля. Мы намеренно не сохраняем имя клиента: для повторного чтения результата достаточно ID и статуса.

Шаг 3. Импортируйте схему записи

Скачать n8n-datatables-save.json

Сохраните JSON-файл, создайте новый workflow в том же проекте и выберите Import from File в меню редактора. Если браузер показывает JSON вместо скачивания, используйте «Сохранить как». Название схемы — ezGPT - Save Order Results. На полотне должно быть пять узлов.

text
Manual Trigger → Test Orders → Split Orders → Prepare Rows → Save Results

Test Orders — Edit Fields (Set), Split Orders — Split Out, Prepare Rows — Code, Save Results — Data table. Если собираете вручную, добавьте эти узлы в указанном порядке. Сохраните workflow ручным, без расписания и публикации.

Шаг 4. Добавьте тестовые заказы

В Test Orders выберите Mode: JSON Output и вставьте объект ниже. Один item содержит массив orders из трёх вымышленных заказов. В импортированном файле этот объект уже задан.

json
{
  "orders": [
    {
      "order_id": "O1",
      "client": "  Анна   Петрова ",
      "amount_minor": "150000",
      "currency": "rub"
    },
    {
      "order_id": "O2",
      "client": "Борис",
      "amount_minor": 0,
      "currency": "RUB"
    },
    {
      "order_id": "O3",
      "client": "",
      "amount_minor": "сумма",
      "currency": "RUB"
    }
  ]
}

amount_minor — сумма в копейках, а не в рублях. Строка «150000» будет проверена и преобразована в число, 0 останется допустимым нулём. Ошибочный заказ O3 сохранится как результат проверки с пустой суммой, а не как заказ на ноль рублей.

Шаг 5. Разделите массив на записи

В Split Orders укажите Field to Split Out: orders и Include: No Other Fields. Выполните цепочку до этого узла: ожидаются три items. Поля каждого заказа должны находиться прямо в json, а не внутри orders.

Шаг 6. Подготовьте строки для таблицы

В Prepare Rows выберите Language: JavaScript, Mode: Run Once for All Items и вставьте код ниже. Он выдаёт только пять полей из структуры таблицы. Отдельная проверка всех ID выполняется до подготовки записей: пустой или повторяющийся очищенный ID останавливает всю схему до Upsert.

javascript
const rows = $input.all().map(item => item.json);
const clean = value => typeof value === 'string'
  ? value.trim().replace(/\s+/g, ' ') : '';
const ids = rows.map(row => clean(row.order_id));
if (ids.some(id => !id) || new Set(ids).size !== ids.length)
  throw new Error('invalid_or_duplicate_order_id');

return rows.map((row, index) => {
  const raw = row.amount_minor;
  const amount = typeof raw === 'number' ? raw
    : typeof raw === 'string' && /^\d+$/.test(raw.trim())
      ? Number(raw.trim()) : NaN;
  const errors = [];
  if (!clean(row.client)) errors.push('client_required');
  if (clean(row.currency).toUpperCase() !== 'RUB')
    errors.push('currency_must_be_RUB');
  if (!Number.isSafeInteger(amount) || amount < 0)
    errors.push('amount_minor_invalid');
  return {
    json: {
      order_id: ids[index],
      status: errors.length ? 'needs_review' : 'ready',
      amount_minor: errors.length ? null : amount,
      errors_text: errors.join('; '),
      validation_version: 'v1',
    },
    pairedItem: { item: index },
  };
});

Число считается допустимым только в безопасном целочисленном диапазоне и не меньше нуля. Строки должны состоять из цифр: null, «1e3» и текст о цене не преобразуются молча в сумму. У невалидного заказа amount_minor становится null, а ошибки объединяются в errors_text. validation_version — наша метка проверки, не автоматическая версия workflow.

Как работает Code и структура items в n8n

Шаг 7. Настройте Upsert по order_id

В Save Results выберите Resource: Row, Operation: Upsert. В Data table укажите By Name: ezgpt_order_results или выберите эту же таблицу From list. При выборе другой таблицы повторно проверьте её колонки.

Must Match: All Conditions. Добавьте одно условие: Column order_id, Condition Equals, Value — Expression ниже. Не используйте status вместо ID: одинаковый статус может быть у нескольких заказов.

text
{{ $json.order_id }}

Mapping Column Mode: Map Automatically. Все пять имён полей Prepare Rows точно совпадают с колонками. В Options оставьте Dry Run выключенным, а в Settings — On Error: Stop Workflow. Если не найдена таблица или не прошла запись, не продолжайте работу так, будто данные сохранены.

Шаг 8. Запишите и проверьте три строки

Выполните весь workflow через Manual Trigger. Затем откройте ezgpt_order_results в Data tables и при необходимости обновите таблицу. Проверяйте именно её строки, а не только OUTPUT Save Results.

  • O1: status ready, amount_minor 150000, errors_text пустой, validation_version v1.
  • O2: status ready, amount_minor 0, errors_text пустой, validation_version v1.
  • O3: status needs_review, amount_minor пустой/null, errors_text «client_required; amount_minor_invalid», validation_version v1.

Строк должно быть три. В поле number не пишите строку «null»: код передаёт настоящее JSON-значение null. Пустая сумма у ошибочного заказа и 0 у готового должны различаться.

Шаг 9. Проверьте повтор и обновление

Повторно запустите схему с тем же JSON. В таблице должны остаться три строки, а их системные id — прежними. Upsert ищет строку по order_id; Insert каждый раз создавал бы новую запись.

Затем в Test Orders замените сумму O1 на строку «160000». Новый запуск должен изменить его сумму до 160000 копеек, сохранив id. У O2 и O3 статус, сумма и errors_text останутся прежними; служебный updatedAt может обновиться, потому что Upsert обрабатывает все три записи. Не редактируйте id вручную.

Такое поведение проверено при последовательных запусках. Наше условие Upsert не создаёт уникальный индекс на order_id и не доказывает отсутствие дублей при конкуренции. На первом этапе не запускайте параллельно несколько writers для одной таблицы.

Шаг 10. Импортируйте независимое чтение

Скачать n8n-datatables-read.json

Создайте второй новый workflow в этом же проекте и импортируйте n8n-datatables-read.json. Его имя — ezGPT - Read Order Results. Здесь только два узла:

text
Manual Trigger → Read Results

В Read Results выберите Resource: Row, Operation: Get, ту же Data table. Conditions оставьте пустыми, Return All включите. Выполните этот workflow отдельно: ожидаются три сохранённые строки. В нём нет Test Orders и записи, поэтому результат приходит из таблицы, а не из входного JSON первой схемы. Порядок строк не считайте гарантированным.

Шаг 11. Получите только ready

В Read Results добавьте условие Column: status, Condition: Equals, Value: обычный текст ready. Оставьте Return All включённым. Выполните чтение: должно вернуться два items с order_id O1 и O2. Запись O3 остаётся в таблице, но не попадает в отфильтрованный результат.

Верните Read Results к чтению всех строк: удалите условие status. Фильтр не удаляет данные, а Return All означает все совпавшие строки, не всегда всю таблицу. Для крупной меняющейся таблицы нужна отдельная стратегия чтения и ограничения объёма; этот пример использует три строки.

Шаг 12. Проверьте неверные данные до записи

В Test Orders схемы записи замените сумму O1 на null и запустите workflow. Таблица должна показать для O1 needs_review и amount_minor null. Это сохранённый результат неуспешной проверки данных; технической ошибки записи в данном случае нет.

Теперь восстановите исходный JSON из шага 4, выполните запись и отдельно чтение всех строк. После этого в учебной копии Test Orders поставьте пустой order_id у O1. Код должен завершиться с invalid_or_duplicate_order_id, а Save Results не должен запуститься. Существующие строки останутся прежними. Аналогично проверьте два одинаковых ID, заменив O2 на « O1 ».

Верните исходный JSON и снова запишите три корректно обработанных результата. Проверка перед Upsert защищает от этих ошибок входа, но не делает запись всего набора атомарной: при сбое хранилища уже записанные строки могут остаться. Не обещайте «всё или ничего» без отдельного механизма транзакций.

Шаг 13. Перезапустите локальный n8n и прочитайте снова

Для установки по нашей Docker-инструкции откройте PowerShell в её папке и выполните команды ниже. На другой установке используйте свой согласованный способ перезапуска. В Cloud не пытайтесь выполнять эти локальные команды; повторное чтение можно проверить без перезапуска сервиса.

powershell
Set-Location "$HOME/n8n-local"
docker compose restart n8n
docker compose ps

Дождитесь, пока редактор снова станет доступен. Откройте Read Order Results и выполните Manual Trigger. Должны вернуться те же три строки, включая нулевую сумму O2 и null у O3. Это новое выполнение, не просмотр прежнего OUTPUT.

В нашей проверке после перезапуска сохранились также системные id. Не удаляйте Docker volume и не используйте down -v для такого теста. Таблицы хранятся в данных экземпляра n8n: сохраняемый том нужен локальной установке, а резервная копия — восстановлению после потери хранилища.

Шаг 14. Проверьте Dry Run и восстановите настройки

В Save Results включите Options → Dry Run. В Test Orders временно поменяйте сумму O1 на 999000. Выполните запись, а затем независимый Read Order Results. В таблице O1 должен остаться на 150000 копеек: Dry Run показывает предполагаемые изменения, но не сохраняет их.

Не выдавайте OUTPUT Dry Run за записанные данные. Верните исходный JSON и выключите Dry Run. Снова выполните запись и чтение. Финальный результат — три строки O1/O2/O3 со значениями из шага 8; оба workflows остаются ручными и неопубликованными.

Если результат отличается

Симптом Причина Что проверить
Table не найдена Другой проект или имя ezgpt_order_results в своём проекте
Число строк растёт Insert вместо Upsert Upsert с условием order_id
Изменения не сохранились Включён Dry Run Выключите его и прочитайте заново
Ошибка колонок Имена или типы отличаются Пять колонок из шага 2
Ноль стал пустым Неверное преобразование суммы Полный код Prepare Rows
После перезапуска нет данных Другое или удалённое хранилище Том n8n и имя выбранной таблицы

Перед подключением рабочих данных

Не храните API-ключи и пароли в Data Tables: используйте штатные credentials n8n. Участники проекта могут иметь доступ к его таблицам, поэтому сначала согласуйте права, состав данных и срок хранения. Наш учебный пример сохраняет только ID и результат проверки, без имени клиента.

Upsert перезаписывает последнее состояние заказа. Для истории всех проверок понадобится отдельная модель с идентификатором события; для полноценного аудита — согласованные правила доступа, изменения и хранения. Data Tables удобны для небольших внутренних наборов, но не заменяют проектирование производственной базы. Контролируйте доступный лимит хранения своего экземпляра.

Не связывайте status ready сразу с оплатой, удалением или отправкой сообщения. Сначала проверьте источник, обновления и ошибки хранения. Ошибка чтения не означает, что данные были удалены, а наличие трёх строк не доказывает полноту реальной выгрузки из CRM.

Что проверено редакцией

13 октября 2026 года сценарий проверен на n8n 2.42.4 в отдельном локальном экземпляре. Таблица и workflows созданы через API n8n, схемы выполнены штатным ручным запуском через API экземпляра. Одиннадцать сценариев: первая запись, повтор, обновление суммы, null, пустой ID, дубли очищенного ID, восстановление, Dry Run, отсутствующая таблица, фильтр ready и чтение после перезапуска. Значения, число строк, стабильность системных id и отсутствие изменений при ошибках входа и Dry Run проверены; отдельно проверено чтение пустой таблицы. Standalone CLI не загрузил модуль Data Tables в этой конфигурации, поэтому успешные тесты не используют CLI execution. Кликовые действия редактора, Cloud, параллельные записи, большие наборы, лимит хранения, атомарность набора и реальные CRM не тестировались. Учебный сервер был доступен только на 127.0.0.1; рабочие workflows не менялись. Обложка — редакционная AI-иллюстрация.

Частые вопросы

Data Tables используют AI и расходуют токены?

Нет. Эта схема выполняет обычную проверку и запись в таблицу n8n. AI-модель и её API-ключ не нужны.

Чем таблица отличается от OUTPUT?

OUTPUT относится к конкретному выполнению. Data Table хранит отдельные строки, которые другой workflow читает в новом запуске. В локальной установке сохраняйте данные экземпляра и резервные копии.

Почему Upsert, а не Insert?

Нужен последний результат для каждого order_id. Upsert обновляет совпавшую строку, а Insert добавляет новую. Это не гарантирует уникальность при одновременных запусках и не хранит историю всех изменений.

Почему у ошибочного заказа сумма null, а не 0?

Ноль — известная допустимая сумма по нашим учебным правилам. null означает, что проверка не разрешила использовать сумму. Статус и errors_text объясняют причину; не превращайте неизвестное значение в ноль.

Можно ли положить туда API-ключи и данные клиентов?

Ключи храните в credentials. Для клиентских данных сначала согласуйте минимальный состав, права участников проекта, срок хранения и резервное копирование. Учебный JSON не является разрешением хранить реальные персональные данные.

Дальше по теме

Похожие материалы