При работе с платформой 1С:Предприятие часто возникает задача взаимодействия со сторонними базами данных, такими как PostgreSQL. Для этих целей в 1С предусмотрен мощный механизм «Внешние Источники Данных». Однако, пользователи иногда сталкиваются с ограничениями при попытке выполнения определенных операций, например, создания новой базы данных или таблиц.
В этой статье мы подробно разберем, почему прямые DDL-команды (Data Definition Language), такие как CREATE DATABASE или CREATE TABLE, не могут быть выполнены через Внешние Источники Данных 1С. Мы также рассмотрим кроссплатформенные альтернативные подходы для выполнения произвольных SQL-скриптов из 1С, особенно в среде Linux, и выясним, как можно эффективно управлять структурой сторонних баз данных.
CREATE DATABASE или CREATE TABLE, не работают через Внешние Источники Данных в 1СДавайте проанализируем основную проблему, с которой столкнулся автор сообщения: попытка выполнить команду CREATE DATABASE через объект внешнего источника данных в 1С, приводящая к синтаксической ошибке 42601. Причина этого кроется в фундаментальном предназначении механизма «Внешние Источники Данных» в платформе 1С:Предприятие.
SELECT);INSERT);UPDATE);DELETE).Механизм Внешних Источников Данных не предназначен для выполнения команд определения данных (DDL – Data Definition Language), которые изменяют или создают саму структуру базы данных, такие как CREATE DATABASE, CREATE TABLE, ALTER TABLE, DROP TABLE и другие.
SQLSTATE: 42601, которая является общим сообщением PostgreSQL о синтаксической ошибке.CREATE TABLE была синтаксически принята СУБД, платформа 1С не смогла бы автоматически “подхватить” и добавить эту новую таблицу в дерево метаданных внешнего источника. Для использования новой таблицы ее необходимо было бы вручную описывать в конфигурации 1С как объект метаданных внешнего источника.Таким образом, мы видим, что ограничение на выполнение DDL-команд является частью архитектуры механизма Внешних Источников Данных и не является ошибкой в SQL-синтаксисе самой команды, а скорее следствием неверного использования интерфейса.
Поскольку механизм Внешних Источников Данных не предназначен для создания самих баз данных, мы должны использовать стандартные инструменты и подходы, предусмотренные как платформой 1С, так и самой СУБД PostgreSQL.
Когда мы разворачиваем новую информационную базу в клиент-серверном варианте с использованием PostgreSQL, платформа 1С предоставляет удобный инструмент для этого. В консоли администрирования серверов 1С, при создании или изменении информационной базы, мы можем указать параметры подключения к PostgreSQL (сервер, порт, имя пользователя, пароль). Здесь есть очень важная опция: «Создать базу данных в случае ее отсутствия». Если мы активируем этот флаг, сервер 1С:Предприятия сам выполнит необходимые команды для создания новой, пустой базы данных на указанном сервере PostgreSQL, которая будет готова для развертывания конфигурации. Это наиболее предпочтительный способ для создания информационных баз 1С.
Стандартной и очень гибкой практикой является предварительное создание базы данных администратором PostgreSQL с использованием встроенных инструментов СУБД. Это особенно актуально, когда требуется тонкая настройка параметров базы данных или когда создание баз данных является задачей системного администратора, а не разработчика 1С.
createdb: Это простая и эффективная утилита, поставляемая с PostgreSQL. Мы можем выполнить ее из командной строки сервера, где установлен PostgreSQL.
createdb -h localhost -U postgres test_db
Здесь -h localhost указывает хост, -U postgres – пользователя с правами на создание баз данных, а test_db – имя новой базы данных.
psql: Более мощный инструмент, позволяющий выполнять произвольные SQL-команды. Мы можем подключиться к любой существующей базе (например, postgres) и выполнить DDL-команду.
psql -h localhost -U postgres
-- Внутри psql
CREATE DATABASE test_db WITH OWNER = postgres ENCODING = 'UTF8' CONNECTION LIMIT = -1;
После создания базы данных одним из этих способов, мы можем указать ее имя при регистрации новой информационной базы в кластере 1С, и платформа будет использовать уже готовую базу.
Итак, мы выяснили, что напрямую создавать базы данных или таблицы через Внешние Источники Данных в 1С невозможно. Однако, задача выполнения произвольных SQL-скриптов (включая DDL) из 1С в кроссплатформенной среде (например, Linux) остается актуальной. Рассмотрим наиболее эффективные методы.
ЗапуститьПриложение())Наиболее универсальным, надежным и кроссплатформенным способом для выполнения произвольных SQL-скриптов является вызов консольного клиента СУБД из 1С с помощью функции ЗапуститьПриложение(). Этот подход позволяет нам полностью использовать функционал клиентских утилит СУБД, таких как psql для PostgreSQL.
Функция ЗапуститьПриложение() позволяет запустить любую внешнюю программу или скрипт, доступный в операционной системе, из кода 1С. Мы можем передать этой программе необходимые аргументы, включая сам SQL-скрипт или путь к файлу с ним.
Для PostgreSQL клиент psql умеет принимать SQL-команды непосредственно в строке или читать их из файла.
psql из 1С для выполнения SQL-скрипта:
Предположим, у нас есть SQL-скрипт create_db_and_sp.sql, который создает базу данных и хранимые процедуры:
-- create_db_and_sp.sql
CREATE DATABASE new_test_db WITH OWNER = postgres ENCODING = 'UTF8' CONNECTION LIMIT = -1;
\c new_test_db; -- Подключаемся к новой базе для создания SP в ней
CREATE OR REPLACE PROCEDURE public.execute_arbitrary_sql(sql_command text)
LANGUAGE plpgsql
AS $$
BEGIN
EXECUTE sql_command;
END;
$$;
Мы можем запустить этот скрипт из 1С следующим образом:
&НаСервере
Функция ВыполнитьSQLСкриптВнешнейУтилитой(ПутьКСкрипту, ИмяПользователяБД, ПарольБД, ХостБД, ПортБД)
// Определяем путь к утилите psql.
// Это может быть "/usr/bin/psql" для Linux или "C:\Program Files\PostgreSQL\...\bin\psql.exe" для Windows.
// Путь должен быть известен и доступен для сервера 1С.
#Если ЛНУКС
ИмяПриложения = "/usr/bin/psql";
#Иначе
ИмяПриложения = "C:\Program Files\PostgreSQL\14\bin\psql.exe"; // Пример
#КонецЕсли
// Формируем параметры для psql
// -h <хост> - сервер БД
// -p <порт> - порт БД
// -U <пользователь> - имя пользователя БД
// -f <файл> - путь к файлу со скриптом
// -d postgres - база данных, к которой подключаемся для выполнения DDL (создание БД)
// Важно: DDL на создание БД не может выполняться в контексте создаваемой БД.
Параметры = СтрШаблон("-h %1 -p %2 -U %3 -d postgres -f %4", ХостБД, ПортБД, ИмяПользователяБД, ПутьКСкрипту);
// Устанавливаем переменную окружения для пароля, чтобы psql не запрашивал его интерактивно
// Это безопасно, так как пароль не будет виден в аргументах процесса
ПеременныеОкружения = Новый Соответствие();
ПеременныеОкружения.Вставить("PGPASSWORD", ПарольБД);
// Запускаем приложение
РезультатЗапуска = ЗапуститьПриложение(ИмяПриложения, Параметры, , ПеременныеОкружения);
Если РезультатЗапуска.КодВозврата = 0 Тогда
Сообщить("SQL-скрипт успешно выполнен.");
Возврат Истина;
Иначе
Сообщить("Ошибка при выполнении SQL-скрипта. Код возврата: " + РезультатЗапуска.КодВозврата);
Сообщить("Вывод консоли: " + РезультатЗапуска.ВыводСтандартнойОшибки);
Возврат Ложь;
КонецЕсли;
КонецФункции
// Пример вызова:
// ПутьКФайлуСкрипта = "C:\temp\create_db_and_sp.sql"; // Или "/tmp/create_db_and_sp.sql" для Linux
// ИмяПользователяPostgres = "postgres";
// ПарольPostgres = "mysecretpassword";
// ХостPostgres = "localhost";
// ПортPostgres = "5432";
// ВыполнитьSQLСкриптВнешнейУтилитой(ПутьКФайлуСкрипта, ИмяПользователяPostgres, ПарольPostgres, ХостPostgres, ПортPostgres);
psql и, возможно, синтаксис пути к скрипту.PGPASSWORD для PostgreSQL) или специальный файл паролей .pgpass. Это предотвращает отображение пароля в списке аргументов процесса, что является хорошей практикой безопасности.Авторы сообщений в форуме нашли другой способ решения задачи, который также является достаточно гибким, но имеет свои нюансы. Их подход заключался в том, что сначала БД создается внешним SQL-скриптом (как мы рассмотрели в стандартных методах), а затем в этой новой БД создается специальная хранимая процедура, через которую можно отправлять произвольные SQL-скрипты. После этого из 1С можно вызывать эту хранимую процедуру, передавая ей нужный SQL-код.
На стороне PostgreSQL создается хранимая процедура (или функция), которая принимает на вход строковый параметр, содержащий SQL-команду, и выполняет ее.
CREATE OR REPLACE PROCEDURE public.execute_dynamic_sql(sql_command text)
LANGUAGE plpgsql
AS $$
BEGIN
EXECUTE sql_command;
END;
$$;
После создания такой процедуры, мы можем вызвать ее из 1С через Внешний Источник Данных:
&НаСервере
Функция ВыполнитьДинамическийSQLЧерезХранимуюПроцедуру(ТекстSQL)
Попытка
ВнешнийИсточник = ВнешниеИсточникиДанных.ИмяВашегоВнешнегоИсточника;
ВнешнийИсточник.ВызватьХранимуюПроцедуру("execute_dynamic_sql", ТекстSQL);
Сообщить("Динамический SQL-скрипт успешно выполнен через хранимую процедуру.");
Возврат Истина;
Исключение
Сообщить("Ошибка при выполнении динамического SQL-скрипта: " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
КонецФункции
// Пример вызова:
// ВыполнитьДинамическийSQLЧерезХранимуюПроцедуру("CREATE TABLE MyNewTable (ID SERIAL PRIMARY KEY, Name VARCHAR(255));");
// ВыполнитьДинамическийSQLЧерезХранимуюПроцедуру("INSERT INTO MyNewTable (Name) VALUES ('Тестовая запись');");
psql, pgAdmin или ЗапуститьПриложение() из 1С).В одном из сообщений упоминался вариант использования COM-объектов (ADO). Этот подход действительно позволяет устанавливать прямое соединение с любой базой данных (включая SQL Server, PostgreSQL с соответствующим ODBC драйвером) и выполнять произвольные SQL-команды. Однако, для кроссплатформенных решений (особенно для Linux) этот метод не подходит, так как COM-технология является специфичной для операционных систем семейства Windows. Мы не будем останавливаться на нем подробно, поскольку автор запроса явно указал на необходимость кроссплатформенности и использования Linux.
В ходе нашего анализа мы подтвердили, что механизм «Внешние Источники Данных» в 1С:Предприятие предназначен исключительно для работы с уже существующими данными (DML-операции) и не поддерживает прямое выполнение DDL-команд, таких как CREATE DATABASE или CREATE TABLE. Попытки выполнения таких команд приведут к ошибкам синтаксиса, таким как SQLSTATE: 42601.
Для создания баз данных 1С на PostgreSQL мы должны использовать стандартные инструменты: либо консоль администрирования серверов 1С с опцией автоматического создания БД, либо утилиты СУБД (createdb, psql, pgAdmin).
Когда же возникает необходимость выполнения произвольных SQL-скриптов (включая DDL) из 1С в кроссплатформенной среде, наиболее рекомендованными и надежными подходами являются:
ЗапуститьПриложение() для вызова консольных утилит СУБД (например, psql). Этот метод обеспечивает максимальную гибкость, кроссплатформенность и безопасность.Выбирая подходящий метод, всегда учитывайте требования к безопасности, кроссплатформенности и удобству администрирования вашего решения.