botruntime
Данные

Таблицы

Схема таблицы, чтение, фильтры и безопасное обновление строк.

Таблица хранит структурированные строки одного бота. Схема объявляется в коде, а данные доступны через типизированный клиент и HTTP API.

Используйте таблицы для заказов, каталогов и других наборов записей. Для контекста одного пользователя или диалога используйте состояние.

Объявите таблицу

src/tables/orders.ts
import { Table, z } from '@holocronlab/botruntime-runtime'

export const OrdersTable = new Table({
  name: 'OrdersTable',
  description: 'Заказы и их текущий статус',
  keyColumn: 'orderNumber',
  columns: {
    orderNumber: z.string().describe('Номер заказа'),
    customerId: z.string().describe('ID покупателя'),
    status: z.enum(['new', 'paid', 'shipped', 'delivered']),
    total: z.string().describe('Сумма заказа, decimal-строка'),
    expectedAt: z.string().optional().describe('Дата доставки YYYY-MM-DD'),
  },
})

Имя должно оканчиваться на Table. Схема синхронизируется при deploy. Удаление колонки или смена типа считаются destructive change и требуют явного подтверждения CLI.

Найдите строки

const { rows } = await OrdersTable.findRows({
  filter: { customerId, status: { $in: ['paid', 'shipped'] } },
  orderBy: 'createdAt',
  orderDirection: 'desc',
  limit: 20,
})

Основные операторы фильтра:

ОператорПример
$eq, $ne{ status: { $ne: 'delivered' } }
$gt, $gte, $lt, $lte{ priority: { $gte: 3 } }
$in, $nin{ status: { $in: ['paid', 'shipped'] } }
$exists{ expectedAt: { $exists: true } }
$regex{ orderNumber: { $regex: '^ORD-' } }
$size{ items: { $size: 2 } }

Объединяйте условия через $and, $or и $not. Неизвестный оператор возвращает 400; платформа не игнорирует часть фильтра.

Создайте строки

await OrdersTable.createRows({
  rows: [
    {
      orderNumber: 'ORD-1042',
      customerId: 'customer-7',
      status: 'paid',
      total: '2490.00',
    },
  ],
})

Денежные значения храните decimal-строками. Календарные даты храните в формате YYYY-MM-DD, если время и часовой пояс не нужны.

Обновите строку

const current = await OrdersTable.getRow({ id: 42 })

await OrdersTable.updateRows({
  rows: [
    {
      id: current.id,
      rowVersion: current.rowVersion,
      status: 'shipped',
    },
  ],
})

rowVersion защищает от потерянного обновления. Если строку уже изменил другой процесс, сервер вернёт конфликт. Перечитайте строку и примените решение к новой версии.

undefined означает «не менять поле», а null очищает nullable-колонку.

Upsert

await OrdersTable.upsertRows({
  keyColumn: 'orderNumber',
  rows: [
    {
      orderNumber: 'ORD-1042',
      customerId: 'customer-7',
      status: 'shipped',
      total: '2490.00',
    },
  ],
})

Upsert подходит для синхронизации по стабильному внешнему ключу. Укажите keyColumn в декларации или в вызове.

Удалите строки

await OrdersTable.deleteRows({
  filter: { status: 'delivered', updatedAt: { $lt: cutoff } },
})

Сначала проверьте тот же фильтр через findRows. Для массового удаления добавьте прикладной лимит или отдельное подтверждение в вашем коде.

HTTP API

Стабильные операции для таблиц генерируются из OpenAPI: Tables API.

Дальше

On this page