При интеграции систем часто возникает задача регулярной сверки данных (например, справочника номенклатуры) между 1С и сторонними информационными системами. Если сервер приложений 1С и СУБД работают под управлением ОС Linux (с базой данных PostgreSQL), стандартные Windows-технологии интеграции (такие как COM-соединение или ADODB) становятся недоступны. Разработчики начинают искать способы прямого обращения к таблицам СУБД с помощью SQL-запросов.
В этой статье мы подробно разберем, как технически реализовать прямое получение данных из PostgreSQL под Linux, проанализируем связанные с этим критические риски и рассмотрим гораздо более надежные, безопасные и юридически чистые архитектурные альтернативы, такие как OData и собственные HTTP-сервисы.
Если перед вами все же стоит жесткая задача прочитать данные напрямую из базы PostgreSQL, необходимо преодолеть две основные технические сложности: динамическую структуру таблиц 1С и настройку ODBC-клиента в операционной системе Linux.
Проблема динамических имен таблиц
В файловой структуре СУБД платформа 1С хранит объекты в таблицах с системными именами (например, _Reference289 для справочника «Номенклатура»). Жестко прописывать такие имена в SQL-запросах крайне опасно. При обновлении конфигурации, реструктуризации базы данных или ее переносе на другой сервер цифровая часть имени таблицы может измениться, что полностью сломает интеграцию.
Чтобы избежать этой проблемы, мы должны динамически получать актуальные системные имена таблиц прямо из метаданных 1С. Для этого воспользуемся встроенным методом платформы ПолучитьСтруктуруХраненияБазыДанных(). Разберем пример кода, который возвращает реальное имя таблицы для справочника «Номенклатура»:
МассивИмен = Новый Массив;
МассивИмен.Добавить("Справочник.Номенклатура");
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных(МассивИмен);
Для Каждого СтрокаТаблицы Из СтруктураБД Цикл
Если СтрокаТаблицы.ИмяМетаданных = "Справочник.Номенклатура" Тогда
ИмяТаблицыСУБД = СтрокаТаблицы.ИмяТаблицыХранения;
Сообщить("Актуальное имя таблицы в PostgreSQL: " + ИмяТаблицыСУБД);
Прервать;
КонецЕсли;
КонецЦикла;
Используя полученную переменную ИмяТаблицыСУБД, мы можем динамически сконструировать безопасный SQL-запрос вида SELECT * FROM _Reference289.
Настройка окружения unixODBC на Linux
Для того чтобы сервер приложений 1С на Linux мог отправлять внешние запросы к PostgreSQL (или принимать их через механизм Внешних источников данных), необходимо настроить ODBC-инфраструктуру на уровне операционной системы. Проанализируем пошаговый процесс настройки:
sudo apt-get update && sudo apt-get install unixodbc unixodbc-dev odbcinst odbc-postgresql
/etc/odbcinst.ini и добавьте в него описание Unicode-драйвера PostgreSQL:
[PostgreSQL-U]
Description = PostgreSQL ODBC driver (Unicode)
Driver = /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so
psqlodbcw.so и libodbcpsqlS.so физически находятся по указанным путям в вашей системе.
DRIVER={PostgreSQL-U};Server=IP_Адрес_Сервера;Port=5432;Database=Имя_Базы_Данных;Uid=Пользователь;Pwd=Пароль;
Такой подход позволит вам отправлять SQL-запросы напрямую к СУБД PostgreSQL из среды Linux. Однако перед внедрением этого решения необходимо детально изучить сопутствующие риски.
Попытки читать данные напрямую из таблиц СУБД в обход платформы 1С создают серьезные проблемы для бизнеса и стабильности системы. Выделим основные риски:
Учитывая все эти недостатки, рассмотрим современные архитектурные паттерны интеграции, которые лишены данных проблем.
Платформа 1С предлагает встроенный готовый инструмент для обмена данными с внешними системами — интерфейс OData. Его главное преимущество заключается в том, что он включается буквально в несколько кликов в конфигураторе и работает полностью по веб-стандартам (HTTP + JSON/XML), соблюдая все лицензионные требования и правила безопасности 1С.
Выясним, как настроить и использовать OData для получения номенклатуры:
Теперь внешняя система может отправить обычный HTTP-запрос GET по адресу:
http://Имя_Сервера/Имя_Базы/odata/standard.odata/Catalog_Номенклатура?$format=json
В ответ внешняя система моментально получит структурированный JSON-пакет со всем содержимым справочника «Номенклатура», готовый для сверки.
Если стандартный механизм OData избыточен или вам нужно передавать только определенный набор полей, отфильтрованный по сложной бизнес-логике, лучшим решением станет разработка собственного HTTP-сервиса внутри конфигурации 1С.
Разберем по шагам создание такого сервиса для отдачи списка номенклатуры внешней системе:
IntegrationService и шаблоном URL /v1/*.Nomenclature и шаблоном /nomenclature.GET и назначьте ему обработчик в модуле сервиса.Напишем программный код обработчика запроса, который выбирает актуальную номенклатуру запросом 1С, упаковывает ее в формат JSON и отправляет клиенту:
Функция ПолучитьНоменклатуру(Запрос)
// Пишем безопасный запрос средствами платформы 1С
Запрос1С = Новый Запрос;
Запрос1С.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
ТаблицаДанных = Запрос1С.Выполнить().Выгрузить();
// Преобразуем таблицу значений в массив структур для сериализации в JSON
МассивРезультатов = Новый Массив;
Для Каждого Строка Из ТаблицаДанных Цикл
СтруктураОбъекта = Новый Структура;
СтруктураОбъекта.Вставить("UUID", Строка(Строка.Ссылка.УникальныйИдентификатор()));
СтруктураОбъекта.Вставить("Code", Строка.Код);
СтруктураОбъекта.Вставить("Name", Строка.Наименование);
СтруктураОбъекта.Вставить("SKU", Строка.Артикул);
МассивРезультатов.Добавить(СтруктураОбъекта);
КонецЦикла;
// Сериализуем данные в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивРезультатов);
СтрокаОтвета = ЗаписьJSON.Закрыть();
// Формируем качественный HTTP-ответ
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(СтрокаОтвета, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Возврат Ответ;
КонецФункции
Преимущества реализации через HTTP-сервисы очевидны: мы полностью контролируем состав передаваемых полей, не нарушаем лицензионную политику фирмы «1С», исключаем возникновение СУБД-блокировок от сторонних запросов и отдаем данные в удобном для интеграции виде. Внешней системе достаточно раз в сутки вызвать этот метод по расписанию для автоматической синхронизации данных.