Перенос справочников и документов из базы 1С в стороннюю базу данных PostgreSQL — распространенная задача при интеграции учетных систем, построении аналитических хранилищ или обмене данными с веб-сервисами. Часто разработчики выбирают путь прямого подключения через технологии COM и ADO (ActiveX Data Objects). Однако на первом же этапе многие сталкиваются с системной ошибкой: «Microsoft OLE DB Provider for ODBC Drivers: [Microsoft][Диспетчер драйверов ODBC] Источник данных не найден и не указан драйвер, используемый по умолчанию».
Разберем детально, почему возникает эта ошибка, как правильно настроить прямое подключение к PostgreSQL и какие штатные альтернативы платформы 1С лучше применить для выгрузки данных.
Посмотрим на типовую строку подключения, вызывающую исключение при выполнении метода Open() объекта ADODB.Connection:
СоединениеАДО.ConnectionString = "Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=postgres;Uid=postgres;Pwd=12345678;";
СоединениеАДО.Open();
Проанализируем ключевые причины возникновения ошибки поиска источника данных:
C:\Windows\SysWOW64\odbcad32.exe. Если же код выполняется на стороне сервера 1С в процедуре с директивой &НаСервере, то разрядность драйвера должна строго соответствовать разрядности службы сервера 1С (для 64-битного сервера необходим 64-битный драйвер, настраиваемый через C:\Windows\System32\odbcad32.exe).Driver={...} должно посимвольно совпадать с записью в системном реестре Windows по пути HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers. В зависимости от установленного дистрибутива драйвер может называться PostgreSQL Unicode, PostgreSQL Unicode(x64) или содержать номер релиза.
СоединениеАДО.ConnectionString = "DSN=ИмяИсточникаPostgres;Uid=postgres;Pwd=12345678;";
СоединениеАДО.Open();
Рассмотрим пример выгрузки номенклатуры с использованием COM-соединения. Для предотвращения падения производительности и ошибок экранирования символов обязательно используем параметризованные запросы или пакетную вставку, а также управляем транзакциями.
&НаСервере
Процедура ВыгрузитьНоменклатуруВPostgres()
Попытка
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.ConnectionString = "Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=my_database;Uid=postgres;Pwd=пароль;";
Соединение.Open();
Исключение
ВызватьИсключение "Ошибка подключения к PostgreSQL: " + ОписаниеОшибки();
КонецПопытки;
// Устанавливаем кодировку сеанса для корректной передачи кириллицы
Соединение.Execute("SET client_encoding TO 'UTF8';");
// Открываем транзакцию для ускорения пакетной записи
Соединение.Execute("BEGIN;");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ЭтоГруппа";
Выборка = Запрос.Выполнить().Выбрать();
Команда = Новый COMОбъект("ADODB.Command");
Команда.ActiveConnection = Соединение;
Команда.CommandText = "INSERT INTO goods (code, name, article) VALUES (?, ?, ?);";
Команда.Parameters.Append(Команда.CreateParameter("pCode", 200, 1, 50));
Команда.Parameters.Append(Команда.CreateParameter("pName", 200, 1, 150));
Команда.Parameters.Append(Команда.CreateParameter("pArticle", 200, 1, 50));
Счетчик = 0;
Пока Выборка.Следующий() Цикл
Команда.Parameters("pCode").Value = Сокращенно(Выборка.Код);
Команда.Parameters("pName").Value = Выборка.Наименование;
Команда.Parameters("pArticle").Value = Выборка.Артикул;
Команда.Execute();
Счетчик = Счетчик + 1;
Если Счетчик % 1000 = 0 Тогда
// Промежуточная фиксация больших массивов
Соединение.Execute("COMMIT;");
Соединение.Execute("BEGIN;");
КонецЕсли;
КонецЦикла;
Соединение.Execute("COMMIT;");
Соединение.Close();
КонецПроцедуры
Важное ограничение: Использование COMОбъект("ADODB.Connection") привязано исключительно к операционной системе Windows. Если рабочий сервер 1С функционирует на базе Linux, этот код работать не будет.
Разберем самый быстрый с точки зрения скорости импорта способ переноса крупных массивов данных. База данных PostgreSQL содержит внутреннюю высокопроизводительную команду COPY, предназначенную для прямой загрузки из текстовых форматов.
UTF-8 с помощью объекта ЗаписьТекста.
COPY goods("code", "name", "article") FROM 'D:/temp/nomenklatura.csv' WITH DELIMITER ';' CSV HEADER ENCODING 'UTF8';
Такой подход исключает задержки сетевого протокола ODBC при построчной обработке и позволяет выгружать сотни тысяч позиций за считанные секунды.
Если задача требует регулярной синхронизации данных, наиболее правильным архитектурным решением внутри платформы 1С:Предприятие является объект конфигурации «Внешние источники данных».
Выясним преимущества работы через внешний источник:
Запрос встроенного языка 1С без написания «сырого» SQL.Для настройки достаточно добавить в ветку дерева метаданных «Внешние источники данных» новый элемент, указать строку соединения через системный DSN и импортировать схему требуемых таблиц базы PostgreSQL.
Если сервер 1С работает под управлением Linux или прямой доступ к порту СУБД 5432 закрыт межсетевыми экранами в целях безопасности, рекомендуется организовать выгрузку через HTTP. Для этого перед базой PostgreSQL развертывается слой API (например, легковесный сервис на Python, Go или готовый шлюз PostgREST).
Со стороны 1С выгрузка формируется с помощью встроенных объектов HTTPСоединение и HTTPЗапрос с телом в формате JSON. Такой метод полностью платформонезависим, масштабируем и не требует инсталляции сторонних драйверов в операционной системе.