В современной разработке на платформе 1С часто возникает необходимость взаимодействия с внешними источниками данных. Одним из самых популярных и легковесных решений для локального хранения или быстрого обмена данными является SQLite. В данной статье мы подробно проанализируем использование нативной внешней компоненты v8sqlite, которая позволяет бесшовно интегрировать SQLite в среду 1С:Предприятие 8 на операционных системах Windows и Linux. Для аналогичной нативной интеграции с базами PostgreSQL можно использовать внешнюю компоненту для работы с PostgreSQL.
Традиционные методы работы с внешними БД через COMОбъект (например, ADO) имеют существенный недостаток — они привязаны к операционной системе Windows. В условиях активного перехода на Linux-серверы и использования веб-клиентов нам требуются кроссплатформенные инструменты. Компонента v8sqlite написана с использованием Native API, что дает нам ряд преимуществ:
Рассмотрим процесс подключения. Сначала нам необходимо поместить файл компоненты в общий макет или макет обработки. После этого мы используем стандартный механизм 1С для загрузки внешних компонент. Разберем программный код для инициализации объекта:
// Установим внешнюю компоненту из макета
РезультатЗагрузки = УстановитьВнешнююКомпоненту("ОбщийМакет.v8sqlite");
Если РезультатЗагрузки Тогда
Подключено = ПодключитьВнешнююКомпоненту("ОбщийМакет.v8sqlite", "SQLiteAddIn", ТипВнешнейКомпоненты.Native);
Если Подключено Тогда
БазаSQLite = Новый("AddIn.SQLiteAddIn.v8sqlite");
КонецЕсли;
КонецЕсли;
После создания объекта БазаSQLite нам необходимо открыть файл базы данных. Если файла не существует, SQLite создаст его автоматически при открытии.
ПутьКБазе = "C:\Data\my_database.db"; // Или путь в Linux формате /home/user/data.db
Если БазаSQLite.Открыть(ПутьКБазе) Тогда
Сообщить("База данных успешно открыта!");
Иначе
Сообщить("Ошибка открытия: " + БазаSQLite.ПоследняяОшибка());
КонецЕсли;
Проанализируем основной метод компоненты — ВыполнитьЗапрос(). Одной из ключевых особенностей v8sqlite является возможность возвращать результат сразу в виде объекта 1С ТаблицаЗначений. Это избавляет нас от утомительного перебора строк и ручного наполнения таблицы.
Рассмотрим пример выполнения запроса с получением результата в таблицу:
ТекстЗапроса = "SELECT id, name, price FROM goods WHERE category_id = 5";
// ФорматОтвета: 0 - ТаблицаЗначений, 1 - Массив массивов (JSON-friendly)
ФорматОтвета = 0;
Результат = БазаSQLite.ВыполнитьЗапрос(ТекстЗапроса, ФорматОтвета);
Если ТипЗнч(Результат) = Тип("ТаблицаЗначений") Тогда
Для Каждого Строка Из Результат Цикл
Сообщить("Товар: " + Строка.name + ", Цена: " + Строка.price);
КонецЦикла;
КонецЕсли;
Важный нюанс типизации: SQLite не имеет жесткого типа данных для дат. Обычно даты хранятся в виде строк или чисел. Автор компоненты реализовал механизм автоматического преобразования. Если вы знаете, что определенные колонки должны быть датами 1С, вы можете передать их список третьим параметром:
КолонкиСДатами = "date_created, date_updated";
Результат = БазаSQLite.ВыполнитьЗапрос("SELECT * FROM orders", 0, КолонкиСДатами);
Выясним, как компоненте удается возвращать сложные объекты 1С. В Native API компоненты не могут напрямую создавать объекты ТаблицаЗначений внутри памяти 1С. Для решения этой задачи автор применил эффективный обходной путь: компонента формирует внутреннее строковое представление таблицы (используя формат ЗначениеИзСтрокиВнутр) и возвращает эту строку. Платформа 1С на своей стороне мгновенно десериализует эту строку в полноценный объект.
Для тонкого клиента, где использование внутренних строк ограничено, предусмотрен режим возврата данных через JSON + XDTO в виде массива массивов. Это позволяет эффективно работать с данными даже в веб-клиенте или при ограниченных правах доступа.
В процессе обсуждения на форуме был поднят вопрос об отсутствии режима «курсора» (построчного чтения). В текущей реализации компонента выгружает весь результат запроса в память сразу. Рассмотрим, как мы можем оптимизировать работу, если выборка содержит миллионы строк:
rowid, по которой очень быстро работает пагинация.GROUP BY, SUM, COUNT), чтобы передавать в 1С уже готовый сокращенный результат.WHERE и JOIN. Это критически влияет на скорость выполнения метода ВыполнитьЗапрос.Разберем пример создания индекса и порционного чтения:
// Создание индекса для ускорения поиска
БазаSQLite.ВыполнитьЗапрос("CREATE INDEX IF NOT EXISTS idx_goods_cat ON goods(category_id)");
// Чтение первой тысячи записей
ТекстЗапроса = "SELECT * FROM goods ORDER BY rowid LIMIT 1000 OFFSET 0";
ТЗ_Порция1 = БазаSQLite.ВыполнитьЗапрос(ТекстЗапроса);
При работе с внешними базами данных всегда существует риск SQL-инъекций. Хотя SQLite является локальной базой, хорошим тоном считается использование параметров. Проанализируем, как безопасно передавать данные из 1С в запрос. На текущий момент рекомендуется использовать экранирование или предварительную подготовку строк, если данные поступают от пользователя.
Также стоит отметить возможность использования PRAGMA-команд для настройки производительности SQLite прямо из кода 1С:
PRAGMA journal_mode = WAL; — включение режима Write-Ahead Logging для повышения параллелизма (чтение не блокирует запись).PRAGMA synchronous = NORMAL; — баланс между скоростью записи и надежностью при сбоях питания.PRAGMA cache_size = 10000; — увеличение кэша страниц в памяти.В ходе дискуссии эксперты предложили альтернативные варианты интеграции, которые могут быть полезны в специфических сценариях:
sqlite3.exe через ЗапуститьПриложение(). Этот метод прост, но крайне медленный из-за создания нового процесса на каждый запрос и записи временных файлов.Таким образом, для большинства задач интеграции 1С и SQLite использование нативной компоненты v8sqlite является наиболее сбалансированным и производительным решением. Мы получаем высокую скорость работы, кроссплатформенность и удобный типизированный результат в виде ТаблицыЗначений. Для ознакомления с другими практическими примерами работы с внешними СУБД подойдёт руководство по подключению и получению данных из SQL в 1С.