tormozit / RDT1C

Подсистема "Инструменты разработчика" для платформы 1С 8
http://devtool1c.ucoz.ru
92 stars 9 forks source link

Расширение функционала инструмента "Структура хранения БД" для работы с СУБД PostgresSQL #246

Closed MelenchukEvgeniy closed 2 years ago

MelenchukEvgeniy commented 2 years ago

Для клиент-серверного варианта работы хочется иметь возможность указывать параметры подключения не только к СУБД MSSQL, но и к PostgreSQL. Соответственно, при работе с PostgreSQL, хочется видеть реальные размеры таблиц - колонки "Размер данные", "Размер индексы" и "Размер общие".

MelenchukEvgeniy commented 2 years ago

Не очищает.

Нужен полный текст ошибки.

Ошибка при получении значения атрибута контекста (DefaultDatabase) {ИнструментыРазработчикаTormozit ОбщийМодуль.ирОбщий.Модуль(39020)}: ИмяБД = ПолучитьСоединениеСУБД().DefaultDatabase; {ИнструментыРазработчикаTormozit Обработка.ирСтруктураХраненияБД.Форма.Форма.Форма(445)}: Если Не ирОбщий.ПодтверждениеОперацииСУБДЛкс() Тогда по причине: Произошла исключительная ситуация (ADODB.Connection): Поставщик не поддерживает это свойство.

tormozit commented 2 years ago

Колонка "Размер общий" пустая по всем строкам

Исправил

SELECT
    pretty_sizes.table_name AS fullTableName,
    pretty_sizes.tabname AS TableName,
    pretty_sizes.tabschema AS tabschema,
    pretty_sizes.table_size/1024 AS DataKB,
    pretty_sizes.indexes_size/1024 AS IndexKB,
    pretty_sizes.total_size/1024 AS ReservedKB,
    c.reltuples::integer AS Rows,
    '' as IndexType
FROM
    (SELECT
        all_tables.table_name AS table_name,
        all_tables.tabname AS tabname,
        all_tables.tabschema AS tabschema,
        pg_table_size(table_name) AS table_size,
        pg_indexes_size(table_name) AS indexes_size,
        pg_total_relation_size(table_name) AS total_size
    FROM
        (SELECT
            ('"'||table_schema||'"."'||table_name||'"') AS table_name,
            table_name AS tabname,
            table_schema AS tabschema
        FROM
            information_schema.tables AS tables
        WHERE table_schema LIKE 'public') AS all_tables) AS pretty_sizes
    LEFT JOIN pg_class AS c
    ON c.oid = tabname::regclass::oid
MelenchukEvgeniy commented 2 years ago

В колонке "Количество строк" есть значения "-1".

tormozit commented 2 years ago

Старайся тексты ошибок вставлять непосредственно в текст сообщения. Потом может быть полезно их искать. А по вложенным файлам найти не получится.

MelenchukEvgeniy commented 2 years ago

SELECT pretty_sizes.table_name AS fullTableName, pretty_sizes.tabname AS TableName, pretty_sizes.tabschema AS tabschema, pretty_sizes.table_size/1024 AS DataKB, pretty_sizes.indexes_size/1024 AS IndexKB, pretty_sizes.total_size/1024 AS ReservedKB, c.reltuples::integer AS Rows, '' as IndexType FROM (SELECT all_tables.table_name AS table_name, all_tables.tabname AS tabname, all_tables.tabschema AS tabschema, pg_table_size(table_name) AS table_size, pg_indexes_size(table_name) AS indexes_size, pg_total_relation_size(table_name) AS total_size FROM (SELECT ('"'||table_schema||'"."'||table_name||'"') AS table_name, table_name AS tabname, table_schema AS tabschema FROM information_schema.tables AS tables WHERE table_schema LIKE 'public') AS all_tables) AS pretty_sizes LEFT JOIN pg_class AS c ON c.oid = tabname::regclass::oid

Да, общий размер тоже работает. Через PgAdmin такой же результат получаю.

MelenchukEvgeniy commented 2 years ago

Старайся тексты ошибок вставлять непосредственно в текст сообщения. Потом может быть полезно их искать. А по вложенным файлам найти не получится.

Хорошо.

tormozit commented 2 years ago

Ошибка при получении значения атрибута контекста (DefaultDatabase)

В общем модуле ирОбщий замени функцию

Функция ПодтверждениеОперацииСУБДЛкс() Экспорт 

    Если ПолучитьСоединениеСУБД() = Неопределено Тогда 
        Возврат Ложь;
    КонецЕсли; 
    ИмяБД = ПараметрыСоединенияADOЭтойБДЛкс().ИмяБД;
    Возврат Вопрос("Вы осознаете риски и ответственность за использование прямого доступа к данным базы """ + ИмяБД + """ и нарушение лицензионного соглашения 1С?", РежимДиалогаВопрос.ДаНет) = КодВозвратаДиалога.Да;

КонецФункции
MelenchukEvgeniy commented 2 years ago

Ошибка при получении значения атрибута контекста (DefaultDatabase)

В общем модуле ирОбщий замени функцию

Заменил. Эта проблема ушла. Но очистка не происходит. Первая ошибка - не хватает ; после каждого truncate, кроме последнего. Проверил в запроснике постгреса.

truncate table _Reference33; --Справочник.БанковскиеСчета.Основная
truncate table _Reference33_VT3869; --Справочник.БанковскиеСчета.ТабличнаяЧасть.ДополнительныеРеквизиты.ТабличнаяЧасть
truncate table _ReferenceChngR3874 --Справочник.БанковскиеСчета.РегистрацияИзменений

Но в инструменте очистки таблиц появилась следующая ошибка:

Ошибка при вызове метода контекста (Open)
{ИнструментыРазработчикаTormozit Обработка.ирСтруктураХраненияБД.Форма.Форма.Форма(452)}:       РезультатЗапроса.Open(ТекстЗапроса, СоединениеADO, adOpenStatic, adLockOptimistic, adCmdText);
по причине:
Произошла исключительная ситуация (PgOleDb): ERROR:  cannot insert multiple commands into a prepared statement
MelenchukEvgeniy commented 2 years ago

В колонке "Количество строк" есть значения "-1".

С этим можно что-то сделать? Похоже, что эти значения соответствуют пустым таблицам.

tormozit commented 2 years ago

С этим можно что-то сделать?

Уберу отрицательный диапазон у колонки.

tormozit commented 2 years ago

В консоли запросов ИР подключенной к СУБД проверь запрос

SELECT 1;
SELECT 1
MelenchukEvgeniy commented 2 years ago

В консоли запросов ИР подключенной к СУБД проверь запрос

SELECT 1;
SELECT 1

Такая же ошибка: Произошла исключительная ситуация (PgOleDb): ERROR: cannot insert multiple commands into a prepared statement

MelenchukEvgeniy commented 2 years ago

Кстати, если в консоли на закладке "ADO" нажимаю кнопку "Эта БД", то автоматически заполняются реквизиты "Сервер БД", "Имя базы", "Пользователь" и "Пароль" (заполняются если я перед этим пользовался инструментом "Структура хранения БД" и указывал там параметры подключения к БД), а вот реквизит "Платформа" устанавливается в значение "MS-SQL ч/з OLEDB" даже если там до этого было указано значение "PostgreSQL ч/з OLEDB".

tormozit commented 2 years ago

Значит в этом поставщике OLEDB нет поддержки пакетных запросов. Ну наверное для бесплатного продукта 2006 года это нормально. Кстати в современной платной версии у них есть и 64-разрядный вариант и поддержка работы со схемой БД и пакетные запросы. Текущий достигнутый с этим бесплатным поставщиком результат уже дает много пользы. Подумаю над другими вариантами подключения.

реквизит "Платформа" устанавливается в значение "MS-SQL ч/з OLEDB" даже если там до этого было указано значение "PostgreSQL ч/з OLEDB"

Исправлю

MelenchukEvgeniy commented 2 years ago

В сухом остатке на текущий момент:

  1. Инструмент "Структура хранения БД" в части размеров страниц работает через 32-разрядный драйвер OLEDB, который нужно предварительно скачать и установить вручную; в части очистки таблиц формируется пакетный запрос, но ограничения драйвера не позволяют его выполнить - можно скопировать текст в запросник постгреса и выполнить там;
  2. Консоли запроса для прямой работы с БД требуется ODBC драйвер (есть и 32 и 64-разрядный) с дополнительной настройкой DSN. Верно?
tormozit commented 2 years ago
  1. Да. Только после ошибки выполнения запроса очистки теперь открывается консоль запросов с текстом запроса очистки, где пользователь может в частности указать другую строку соединения с другим драйвером ODBC
  2. Да. Точнее в консоли запросов можно использовать любой доступный драйвер, т.к. можно редактировать строку соединения.
tormozit commented 2 years ago

Кстати даже с этим урезанным поставщиком OLEDB в консоли запросов ИР можно выполнить пакетный запрос очистки командой "Выполнить все запросы (F5)" в структуре запроса, т.к. запросы пакета там выполняются по одному.

изображение

tormozit commented 2 years ago

реализовано в 6.41

MelenchukEvgeniy commented 2 years ago

Здорово! Благодарю) А как эту задачу закрыть? Или её не нужно закрывать?

tormozit commented 2 years ago

кнопка "Close issue" внизу

MelenchukEvgeniy commented 2 years ago

Ещё раз спасибо!) Если нужна будет какая-нибудь помощь в тестировании - я завсегда "за")

tormozit commented 2 years ago

На всякий случай замечу, что лучше закрывать заявку когда проверил исправление в релизе.

MelenchukEvgeniy commented 2 years ago

Хорошо, я здесь ещё неопытен)

PythonOfJungle commented 1 year ago

Предложение полностью изменить существующий способ подключения через драйвер PGOLEDB.DLL на стоковый ODBC через MS OLEDB. Сейчас точно также подключается MySQL. В макете Обработки/ирКонсольЗапросов/ПлатформыADODB поменять строку подключения для PostgreSQL на Driver={PostgreSQL ODBC Driver(Unicode)}; SERVER=!БазаСервер!; DATABASE=!БазаИмя!; UID=!Пользователь!; PWD=!Пароль!; Остальные параметры строки соединения не нужны. После этого при установленном из родного комплекта драйвере psqlODBC все работает нативно и в "Консоли запросов", и в инструменте "Структура хранения БД". Только надо тогда текст ошибки изменить (Обработки/ирКонсольЗапросов/МодульОбъекта[782]). Примерно так: Установите от имени администратора с помощью Application Stack Builder из инструментов PostgreSQL драйвер psqlODBC той же разрядности, что используемое приложение

tormozit commented 1 year ago

@MelenchukEvgeniy Можешь сделать и проверить модификацию от @PythonOfJungle ?

tormozit commented 1 year ago

@PythonOfJungle Предположим пользователь не знаком с PostgreSQL и у него на клиентском компьютере не установлено какого либо ПО этой СУБД, но он запустил ИР в клиент-серверной базе на PostgreSQL и хочет посмотреть размеры таблиц БД. В текущей реализации он достаточно быстро скачает и зарегистрирует нужную библиотеку, затем получит параметры подключения от администратора и выполнит неявно нужный прямой запрос к СУБД в инструменте "Структура хранения БД (ИР)".

В предлагаемой тобой модификации ему придется изучать, что такое "Application Stack Builder из инструментов PostgreSQL драйвер psqlODBC" и как это правильно устанавливать и желательно без лишних компонент. Это кажется существенным усложнением в описанном мной случае. Попробуй упростить пользовательский путь.

PythonOfJungle commented 1 year ago

@tormozit Логично. Драйвер psqlODBC есть отдельно от общего комплекта. Вот здесь https://www.postgresql.org/ftp/odbc/versions/msi/ Можно смело качать последний, в установщике обе разрядности сразу. Эту же ссылку можно дать в тексте ошибки. Нюанс только в том, что он в системе называется не "PostgreSQL ODBC Driver(Unicode)", а "PostgreSQL Unicode". Строка подключения будет такая: Driver={PostgreSQL Unicode}; SERVER=!БазаСервер!; DATABASE=!БазаИмя!; UID=!Пользователь!; PWD=!Пароль!; Так даже лучше, поскольку штатный установщик PostgreSQL AppStackBuilder скачивает и ставит не самую последнюю версию. Полагаю, что те пользователи, у которых установлен PostgreSQL и уже вручную установлен комплектный драйвер, сами догадаются поправить строку подключения. А если не догадаются, то ничего страшного, драйверы в системе мешать друг другу не будут.

image 13.00 - комплектный драйвер 13.02 - из ссылки выше На самом деле это один и тот же драйвер. Для меня только остается загадкой, почему в списке 64-разрядных драйверов две строки - обычная и с указанием "(x64)". 32-разрядный драйвер находится, как ему и положено, в своем списке. Может для совместимости сделали две строки регистрации. В любом случае "PostgreSQL Unicode" работает и для 32-битного клиента, и для 64-битного.

tormozit commented 1 year ago

Создал задачу на добавление поддержки ODBC драйвера https://www.hostedredmine.com/issues/954415

PythonOfJungle commented 1 year ago

@tormozit Сначала вот так и хотел - добавить еще один вариант. Но потом посмотрел код. Если добавить новую строку в список подключения, то открытым останется вопрос, как будет работать инструмент "Структура хранения БД". Поэтому в итоге предложение было не добавить строку а заменить текущую. MySQL же точно также подключается. Вообще говоря, насколько я понимаю, специфические OLE-поставщики в опенсорсе не разрабатывают как раз по той причине, что есть платформенно-независимая технология ODBC и есть универсальный конвертер ODBC > MS OLEDB. Соответственно нет смысла делать для каждой СУБД собственный OLEDB. Хотя проприетарные, конечно, есть.

tormozit commented 1 year ago

Реализовано в 6.53

MelenchukEvgeniy commented 1 year ago

@MelenchukEvgeniy Можешь сделать и проверить модификацию от @PythonOfJungle ?

Добрый вечер. Прошу прощения за долгую реакцию. Дома 1С сейчас не работает. Могу проверить только завтра на работе, но уже неактуально как я понимаю?

tormozit commented 1 year ago

@MelenchukEvgeniy Эта правка вошла в релиз. Но без второй проверки. Теперь уже все будут проверять в релизе =)

PythonOfJungle commented 1 year ago

@tormozit Все отлично работает, спасибо :)