При работе с внешними источниками данных, особенно при подключении к СУБД PostgreSQL, разработчики 1С могут столкнуться с неожиданной проблемой. Платформа формирует SQL-запросы, в которых имена таблиц и полей заключены в двойные кавычки и написаны в верхнем регистре, что приводит к ошибке ОШИБКА: отношение "..." не существует. Давайте детально разберемся, почему это происходит и как настроить взаимодействие между 1С и PostgreSQL, чтобы избежать подобных ошибок.
Проанализируем ситуацию, с которой столкнулся автор. Есть задача — из метаданных 1С создать структуру таблиц во внешней базе данных PostgreSQL, а затем работать с этими данными из 1С. Однако после создания таблиц запросы из платформы завершаются с ошибкой.
Корень проблемы лежит в одновременном действии двух факторов: специфики формирования SQL-запросов платформой 1С и правил обработки идентификаторов в PostgreSQL.
Рассмотрим пример. Допустим, в PostgreSQL была создана таблица с помощью следующего скрипта:
CREATE TABLE "uod_teamcenter".spm_pz_gm_rev(
item_id CHARACTER VARYING (128),
revision CHARACTER VARYING (20),
revision_id CHARACTER VARYING (160),
last_mod_date TIMESTAMP,
name CHARACTER VARYING (256),
tc_uid CHARACTER VARYING (20),
guid_pac CHARACTER VARYING (40)
);
Несмотря на то, что имя схемы uod_teamcenter взято в кавычки, имя самой таблицы spm_pz_gm_rev и имена ее полей — нет. Здесь и кроется первая важная особенность PostgreSQL.
Правило PostgreSQL №1: Если идентификатор (имя таблицы, поля, схемы) не заключен в двойные кавычки, PostgreSQL автоматически приводит его к нижнему регистру. Таким образом, приведенный выше скрипт на самом деле создаст таблицу с именем spm_pz_gm_rev.
Теперь посмотрим, какой запрос генерирует платформа 1С для чтения данных из этой таблицы:
SELECT
T1."ITEM_ID",
T1.REVISION,
T1."REVISION_ID",
T1."LAST_MOD_DATE",
T1.NAME,
T1."TC_UID",
T1."GUID_PAC"
FROM
"UOD_TEAMCENTER"."SPM_PZ_GM_REV" T1
LIMIT 1000
Обратите внимание на несколько моментов:
SPM_PZ_GM_REV и схемы UOD_TEAMCENTER написано в верхнем регистре и заключено в двойные кавычки.ITEM_ID, REVISION_ID) также в верхнем регистре и в кавычках, а другая часть (REVISION, NAME) — без кавычек.Здесь мы сталкиваемся со второй важной особенностью PostgreSQL.
Правило PostgreSQL №2: Если идентификатор заключен в двойные кавычки, он становится чувствительным к регистру. СУБД будет искать объект с именем, в точности совпадающим с тем, что указано в кавычках.
В итоге возникает конфликт: мы создали таблицу spm_pz_gm_rev (в нижнем регистре), а 1С пытается обратиться к таблице "SPM_PZ_GM_REV" (в верхнем регистре). Для PostgreSQL это два совершенно разных объекта, и, конечно, она не находит второй, возвращая ошибку "отношение не существует".
Платформа "1С:Предприятие" стремится обеспечить точное соответствие имени объекта в метаданных (свойство Имя в источнике данных) и имени в физической базе. Чтобы гарантировать это, особенно при наличии в именах спецсимволов или разного регистра, 1С заключает такие идентификаторы в кавычки.
Как показало обсуждение на форуме, триггером для такого поведения часто служит наличие в имени символа подчеркивания _. Хотя этот символ является стандартным для SQL, платформа 1С, видя его, перестраховывается и заключает идентификатор в кавычки, чтобы сохранить имя "как есть". Попутно, как мы видим, она также преобразует его в верхний регистр.
Поля REVISION и NAME не были взяты в кавычки, потому что их имена состоят только из латинских букв и не содержат спецсимволов.
Чтобы подружить 1С и PostgreSQL, нужно привести их к "общему знаменателю". Необходимо создавать структуру таблиц в PostgreSQL именно в том виде, в котором 1С ожидает ее увидеть. Вот пошаговая инструкция.
Используйте единый стиль именования. Самой надежной и общепринятой практикой для PostgreSQL является стиль snake_case, то есть все слова в нижнем регистре, разделенные символом подчеркивания (например, user_invoices, contract_date).
Создавайте объекты в PostgreSQL с кавычками и в верхнем регистре. Это самый прямой способ решить проблему. Если вы знаете, что 1С будет генерировать запрос к таблице "SPM_PZ_GM_REV", то и создавать ее нужно с таким же именем. Ваш скрипт создания таблицы должен выглядеть так:
CREATE TABLE "uod_teamcenter"."SPM_PZ_GM_REV" (
"ITEM_ID" CHARACTER VARYING(128),
"REVISION" CHARACTER VARYING(20),
"REVISION_ID" CHARACTER VARYING(160),
"LAST_MOD_DATE" TIMESTAMP,
"NAME" CHARACTER VARYING(256),
"TC_UID" CHARACTER VARYING(20),
"GUID_PAC" CHARACTER VARYING(40)
);
Важный момент: в этом случае все идентификаторы, включая те, что не содержат подчеркивания, следует заключать в кавычки и писать в верхнем регистре. Это создаст в базе данных объекты с именами в верхнем регистре, и запросы от 1С будут успешно их находить.
Соблюдайте точное соответствие в метаданных 1С. Убедитесь, что в конфигураторе 1С, в объекте метаданных "Внешний источник данных", свойство Имя в источнике данных для таблиц и полей в точности совпадает с тем, как они будут созданы в PostgreSQL (с учетом регистра). Если вы решили использовать верхний регистр в базе, то и в метаданных 1С имена должны быть в верхнем регистре (SPM_PZ_GM_REV, ITEM_ID и т.д.).
Альтернативный вариант: только нижний регистр. Можно попробовать другой подход: создавать все объекты в PostgreSQL в нижнем регистре и без кавычек, и точно так же указывать их имена в метаданных 1С (в свойстве Имя в источнике данных). В теории, если 1С увидит в своих метаданных имя spm_pz_gm_rev, она может сгенерировать запрос вида FROM "spm_pz_gm_rev", который PostgreSQL поймет правильно. Этот вариант требует проверки, так как поведение платформы может зависеть от ее версии, но он более идеологически верен для PostgreSQL.
Итог: Проблема "отношение не существует" при работе 1С с PostgreSQL — это классический конфликт чувствительности к регистру. 1С заключает идентификаторы со спецсимволами в кавычки и приводит к верхнему регистру, а PostgreSQL по умолчанию работает с нижним регистром (если имена не в кавычках). Самое надежное решение — принудительно создавать таблицы и поля в PostgreSQL с именами в верхнем регистре и в двойных кавычках, чтобы они в точности соответствовали тому, как к ним будет обращаться платформа 1С.