Переезд MSSQL>PostgreSQL (обмен опытом)

Здесь обсуждаем систему TDM/PDM/Workflow Lotsia PDM PLUS (PartY PLUS).
Ответить
Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

Всем привет, может кому пригодится
переезжаем с LotsiaPDM4.4 (15 лет/25 лицензий)->LotsiaPDM5.8 (2 года/10 лицензий)(текущая LotsiaPDM6.1)(MSSQL Server2005/WinServer2003) на PostgreSQL16-17 (Windows8 потом Linux)

1. LotsiaPDM4.4->LotsiaPDM5.8.
Продолжая использовать LotsiaPDM4.4 устанавливаем на часть клиентов LotsiaPDM5.8 (со своим ключем) - убеждаемся что все работает (в рамках одной БД): !!ничего не меняем в настройках LotsiaPDM5.8 - меняя интерфейс если нужно только в LotsiaPDM4.4. Мы отработали в этой сдвоенной схеме (в одной БД) 1 год

2. отказ от LotsiaPDM4.4 в пользу LotsiaPDM5.8
в интерфейсе LotsiaPDM5.8 на всех формах убрать старые tooltip (очень много неприятностей) и переопределить их в свойсвах: если не чистить - формы дают ошибки. После настройки LotsiaPDM4.4 перестает отображать формы - отключаем ее, переходим полностью на работу в LotsiaPDM5.8

3. Устанавливаем БД PostgreSQL и создаем пустую БД.
Через CreateDB (не требует ключа) от последней доступной версии LotsiaPDM - подключаемся к созданной БД PostgreSQL и импортируем туда текущую БД MSSQL - у нас данная процедура занимает 4 часа (выходные когда в БД не поступает новая инфа). Мы использовали CreateDB от LotsiaPDM6.1 (хотя лицензии у нас LotsiaPDM5.8 - но CreateDB от нее некорректно создавал пользователей lsdbo в PostgreSQL)

4. Подключаемся в клиенте LotsiaPDM5.8 к базе PostgreSQL. С этого момента у нас две разные БД MSSQL и PostgreSQL в рамках одной версии LotsiaPDM и ее ключа

5. Активируем в PostgreSQL нужных юзеров через клиента LotsiaPDM5.8

6. Сервер. Переписываем все пользовательские функции и хранимые процедуры БД от MSSQL в PostgreSQL (отличия по синтаксису небольшие (null - заменить на coalesce, + заменить на ||, вызов хп заменить exec на call, чуствительно к регистру, ilike и т.д. dateadd https://www.sqlines.com/sql-server-to-postgresql) - плюсом есть много готовых расширений, но обратите внимание на возвращаемые типы данных, - немного отличаются от MSSQL и в скриптах действий LotsiaPDM - требуют более четкого контроля типов возвращаемых значений).
У нас порядка 50 функций. - Пара недель. Убеждаемся в очень низкой скорости PostgreSQL - оптимизируем функции и настройки БД (в общем то безрезультатно = железо под сервер в данном случае решающий фактор) - + 2 месяца

7. LotsiaPDM. SQL запросы на Формах, Действиях, Скриптах, Отчетах - два варианта по переходу
7.1. отдельно в новой БД PostgreSQL настроить и проверить весь функционал LotsiaPDM5.8
+ купить модуль репликации настроек (деньги смешные но их нет)) )
+ выгрузить настройки из тестовой PostgreSQL + импортировать текущую БД MSSQL в новую PostgreSQL + реплицировать в нее сверху настройки тестовой PostgreSQL
7.2. не покупать модуль репликации настроек
+ максимально подготовить БД MSSQL на работу в мульти базовом режиме)) - чтобы после импорта сразу перевести сотрудников на работу в новой базе PostgreSQL
идем по этому варианту - недостаток один - отчеты если они на динамических SQL придется вручную переписать (если отчеты на пользовательских функция БД - ничего делать не нужно)

8. настраиваем мульти базу на основе LotsiaPDM MSSQL = кроссплатформенные кастомные настройки БД
мы ведем БД с 2006 года за это время в плане кастомизации накопилось более 200 форм + более 600 действий + более 100 отчетов, из особенностей есть быстрый пользователь (права на чтение SQL всех объектов БД минуя права LotsiaPDM)
- на одном компьютере открываем два клиента LotsiaPDM5.8/PostgreSQL и LotsiaPDM5.8/MSSQL + два IDE MSSQL Studio и PgAdmin PostgreSQL (клиенты запущенные на одном компьютере захватывают только одну лицензию Guardant)
- на LotsiaPDM5.8/PostgreSQL тестируем основные/базовые (не все) действия и формы
- на LotsiaPDM5.8/MSSQL - правим - копируем в LotsiaPDM5.8/PostgreSQL - тестируем ошибку и дальше по кругу

9. кастомная кроссплатформенность БД
9.1. для использования на формах объектов и действий
- создаем (у одного из своих системных объектов LotsiaPDM) - строковый атрибут - тип БД (значения например mssql или pstgr)
- создаем пользовательскую функцию БД (и в MSSQL и в PostgreSQL) возвращающую это значение, например в PostgreSQL

Код: Выделить всё

 CREATE OR REPLACE FUNCTION lsdbo.ric_get_type_bd(
	)
    RETURNS text
    LANGUAGE 'sql'
    COST 100
    IMMUTABLE SECURITY DEFINER PARALLEL UNSAFE
    SET search_path=party_user
AS $BODY$
/*
2025 05 31
получить тип бд mssql или pstgr 
*/
  
 SELECT vv.value  
  FROM lsdbo.value_string vv left join lsdbo.attrib_value av on vv.id = av.Value_ID 
where vv.attrib_id = 3000000000121 and 
      av.object_id = 100002307000000
$BODY$;
на формах используем вычисляемое поле - например type_db

Код: Выделить всё

f_ExecSQLSelect_3( 'select LSDBO.Ric_Get_Type_bd()','','','char(15)',10)
и используем его например так

Код: Выделить всё

if((find<>'' or find<>'Выберите запись') and suggested<>'',

case(type_db
when "mssql" then 
  f_ExecSQLSelect_3( 'exec LSDBO.Ric_Get_XmlParser_ForForms ~'' +  suggested  +  '~', ~'/'+'/sg[i1="' + find + '"]/i2~'','','','char(255)',10)
when "pstgr" then  
  f_ExecSQLSelect_3( 'call LSDBO.Ric_Get_XmlParser_ForForms(~''+  suggested  + '~', ~'/'+'/sg[i1="' + find + '"]/i2~',~'~')','','','char(255)',10) 
 
),

'')

9.2 для использования в действиях (скрипты)
- мы используем свое подключение к БД из скриптов (поскольку работаем из старых версий и много всего уже написано), например так
- в модуле(скрипте vbscript) по работе с БД добавляем константу (обратите внимание для PostgreSQL увеличиваю время на ожидание ответа от запроса)

Код: Выделить всё

Option Explicit          'требование объявления переменных
Const pstgr=true	'если true работаем в синтаксисе postgresql

' функция создания и открытия подключения к базе данных
Function ADODB_Connected
  If IsObject(cn) And TypeName(cn) = "Connection" Then
      ADODB_Connected=True
'      msgbox "Соединение уже существует"
      Exit Function
  Else
      On Error Resume Next
      set cn = CreateObject("ADODB.Connection")

	'--POSTGRESQL--
	if not pstgr then		
          cn.Open "Provider=SQLOLEDB;Data Source=win2003;Initial Catalog=crm;User ID=имя быстрого пользователя;Password=его пароль;"
          cn.CommandTimeout=30                                                               ' !!! 30 секунд на выполнение запроса к БД
'	  msgbox cn.CommandTimeout
	else
	  cn.Open "Driver={PostgreSQL UNICODE};Server=web-crm;Port=5432;Database=crm_580_new;UID=имя быстрого пользователя;PWD=его пароль;" 
	  cn.CommandTimeout=60*10                                                          ' !!! 10 минут на выполнение запроса к БД
	end if
	'--POSTGRESQL--				

      If Err.Number = 0 Then
          ADODB_Connected = True
'          msgbox "Новое соединение"
          Exit Function
        Else
        '  ShowError ("Подключение к БД")
          ShowCnError ("Подключение к БД")
          ADODB_Connected = False
          If Not cn Is Nothing Then Set cn = Nothing
        End If
  End If
End Function
- и используем ее например так

Код: Выделить всё

 ' Прочтем Инфу из БД
    If DataBase.ADODB_Connected Then                                                                                       ' если подключиться удалось работаем иначе нет
      If DataBase.ADODB_RecordSet Then                                                                                      ' если удалось создать recordset тоже работаем

	'--POSTGRESQL--
	if not DataBase.pstgr then
 	  sql = "select convert(varchar,rdStatus,104), " & _
                  "rExecuter, " & _ 
                  "rType, " & _  
                  "rName, " & _ 
                  "rCompany " & _
                  "from LSDBO.Ric_Get_attrRequest(0,100004487800000,'Деп,Подч,ПлРб,Req','','',0,'') " & _ 
                "where rStatus='подтверждено' and ((DATEDIFF(day, rdStatus, GETDATE())= 1) " & _ 
                   "or (rdStatus BETWEEN DATEADD (day, 42 , rdStatus) and DATEADD (day, 48 , rdStatus )) " & _ 
                   "or (rdStatus BETWEEN DATEADD (day, 115 , rdStatus) and DATEADD (day, 125 , rdStatus )) " & _ 
                   "or (DATEDIFF(month, rdStatus, GETDATE())>6)) " & _ 
                   "and isobject_id in (select rw.id From lsdbo.object_type tw inner join lsdbo.object_reference rw on rw.type_id = tw.id and rw.author_id=" & cStr(idDB) & ") " & _
            "order by rcDate desc" 'rCompany, rcDate desc"
	else
	  sql = "select TO_CHAR(rdStatus, 'dd.mm.yyyy'), rExecuter, rType, rName, rCompany from LSDBO.Ric_Get_attrRequest(0,100004487800000,'Деп,Подч,ПлРб,Req','','',0,'') where  " & _
	    "rStatus='подтверждено' and ((abs(DATE_PART('day',rdStatus-CURRENT_DATE))=1) or (rdStatus BETWEEN (rdStatus + INTERVAL '42 day') and (rdStatus + INTERVAL '48 day')) or (rdStatus BETWEEN (rdStatus + INTERVAL '115 day') and (rdStatus + INTERVAL '125 day'))  " & _ 
     	    "or (abs((DATE_PART('YEAR', rdStatus) - DATE_PART('YEAR', CURRENT_DATE)) * 12 + (DATE_PART('Month', rdStatus) - DATE_PART('Month', CURRENT_DATE)))>6)) and isobject_id in (select rw.id From lsdbo.object_type tw inner join lsdbo.object_reference rw on rw.type_id = tw.id and rw.author_id=" & cStr(idDB) & ")  " & _
               "order by rcDate desc" 
	end if
 	'--POSTGRESQL--
... 
9.3. пара моментов
9.3.1 пустые атрибуты EMPTY в MSSQL сохраняются нормально в виде AttribSet ( a_Object , LinkID_0 , fTel , trim(tel))
теже пустые атрибуты в PostgreSQL не сохраняются в EMPTY, нужен явно NULL - делаем универсальное решение
AttribSet ( a_Object , LinkID_0 , fTel , if (tel="",Null_S(),trim(tel)) )
9.3.2 если у вас есть парсинг xml через xpath по условию "//name переписываем как "/"+"/name (чтобы не воспринималось LotsiaPDM как комментарий //)
может еще что всплывет - напишу


День переезда
1. создать пустую рабочую БД PostgreSQL
2. импортировать текущую 'мульти' БД MSSQL в PostgreSQL
3. из тестовой БД PostgreSQL выгрузить все свои пользовательские процедуры и функции например так у нас все имена с префиксом

Код: Выделить всё

=# SELECT pg_get_functiondef(oid) FROM pg_proc p WHERE p.pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'lsdbo' and proname LIKE 'ric_%');
и загрузить их в новую рабочую БД PostgreSQL
4. сопоставить/юзеров из клиента LotsiaPDM
5. поменять в БД только два значения
-значение атрибута с типом БД
-константу с типом БД в скриптах
и все.... )) я так предполагаю

морально быть готовым к моментальному (пока мало данных успеет поступить до первой ошибки) 'откату' = просто переключению клиента обратно на MSSQL, или быстрой быстрой фиксации ошибки в уже новой боевой БД PostgreSQL
)))

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

off
странное поведение динамического запроса для postgresql при вызове из скрипта vbscript lotsia
у нас штатный вызов атрибутов к объектам такой например (в mssql везде используем), для postgresql с учетом синтаксиса выглядит так

Код: Выделить всё

select 
	ffio, '{' || CAST(ucn as text) || '}' || CAST(rw.id as text) 
from 
	lsdbo.Ric_Get_chUsers(100004487800000) rw left join 
	lsdbo.attrib_value_view av0 on rw.id=av0.object_id and av0.attrib_id=3000000000122 left join 
	lsdbo.value_string_view vv0 on av0.value_id=vv0.id and av0.attrib_id=3000000000122 
where 
	  fID>0 and vv0.value = 'Менеджер'   order by ffio
по каким то причинам фильтр vv0.value = 'Менеджер' - не работает, из скрипта но из IDE PgAdmin работает....
пофиксили переписав запрос на

Код: Выделить всё

select 
	ffio, '{' || CAST(ucn as text) || '}' || CAST(rw.id as text) 
from 
	lsdbo.Ric_Get_chUsers(100004487800000) rw
	cross join lateral(
		select max(sv.value) as sValue
        from LSDBO.value_string sv left join LSDBO.attrib_value av on av.Value_ID = sv.id
        where rw.id = av.Object_ID and av.Attrib_ID = 3000000000122) vv0	
where  fID>0 and vv0.sValue = 'Менеджер'   order by ffio
тоже самое просто вид сбоку - так из скрипта работает... в чем дело не знаю, буквы русские? но и внизу русские
если из первого варианта фильтр vv0.value = 'Менеджер' убрать - работает...
в общем не знаю... просто для информации

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

нашел (ошибка типа copy/paste... скриптов из базы MSSQL в базу PostgreSQL) короче в проблемном запросе читал из вьюшки _view - в нормальном напрямую из таблицы
_view возвращала тип сравниваемого столбца типа text а таблица character varyng(255)

и сравнение vv0.value = 'Менеджер' с типом текст (при внешнем обращении через объект "ADODB.Connection","ADODB.Recordset") не работало а с типом vv0.value::varchar = 'Менеджер' работает

убило то что PgAdmin работает в сравнении нормально так (без конвертации) и так (с конвертацией)... никогда бы не подумал)) = отказываюсь от _view (это все проблемы длинной разработки = очень много лишнего (но на те моменты актуального) понаписано)

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Старик Крупский
Активный участник
Сообщения: 805
Зарегистрирован: 27 июл 2006, 22:17
Откуда: Москва

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Старик Крупский »

Я тестировал Оракловую базу, залитую в ПГ. То, что Оракл глотает не глядя, например, соединение через join более двух таблиц с атрибутами, ПГ разжевать не может. Переделываю все на подзапросы, ПГ начинает летать.
"Лучше меньше, да лучше" (C)
Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

ничего себе кто появился!!!!!!!!!!!!!!!!!! ПРИВЕТ!!
пример в студию в синтаксисе oracal и postgresql (я тоже от скорости pg вешаюсь. пытались на resql.ru (https://resql.ru/forum/topic.php?fid=46&tid=2187185, https://resql.ru/forum/topic.php?fid=53&tid=2187215) оптимизировать запросы - ничего не вышло практически)

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Старик Крупский
Активный участник
Сообщения: 805
Зарегистрирован: 27 июл 2006, 22:17
Откуда: Москва

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Старик Крупский »

Привет ))

На локальной базе ПГ этот запрос выполняется 1.184 сек., на сетевом Оракле на далеком и медленном сервере 0,117 сек.:
select obj.description
from lsdbo.object_reference_view obj, lsdbo.attrib_value_s_v vs, lsdbo.attrib_value_s_v vs2
where obj.id = vs.object_id and obj.id = vs2.object_id
and obj.type_id = 100000001013006 /*Сотрудник*/
and vs.attrib_id = 100000001713006 /*Должность*/
and vs.value_aid = 100000001713006 /*Должность*/
and vs.value0 = 'Главный инженер проекта'
and vs2.attrib_id = 100000512113098 /*Филиал*/
and vs2.value_aid = 100000512113098 /*Филиал*/
and vs2.value0 = 'М'

А этот на локальном ПГ не более 0.394 сек., а на том же Оракле столько же, сколько и предыдущий:
select obj.description
from lsdbo.object_reference_view obj
where obj.type_id = 100000001013006 /*Сотрудник*/
and exists (select 1 from lsdbo.attrib_value_s_v vs where obj.id = vs.object_id
and vs.attrib_id = 100000001713006 /*Должность*/
and vs.value_aid = 100000001713006 /*Должность*/
and vs.value0 = 'Главный инженер проекта')
and exists (select 1 from lsdbo.attrib_value_s_v vs where obj.id = vs.object_id
and vs.attrib_id = 100000512113098 /*Филиал*/
and vs.value_aid = 100000512113098 /*Филиал*/
and vs.value0 = 'М')
"Лучше меньше, да лучше" (C)
Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

нет, - это не совсем то, типа просто кеш и фильтр, на счет летает... = интересно было бы посмотреть на запрос возвращающий много данных (в плане количества объектов строк и количества их значений атрибутов столбцов) все тормоза именно здесь, +/- помогает vacuum таблиц значений, и добавление своих индексов на большие таблицы (>1 миллиона записей) у нас некоторые запросы в PG выполняются 5мин после кеша - 20 сек а в MSSQL - все летит на 1-10 сек

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

9.3.3 у пользователей в настройках сброcить (у нас во всяком случае) права на контакты (некоторые не видят f_GetGroupID('Менеджеры')) - под админом ок под некоторыми старыми юзерами не работало
9.3.4 в скриптах (vbscript) везде написать обертки для mssql

Код: Выделить всё

 "select top(1)...
для postgresql

Код: Выделить всё

"Select ... limit(1)
- у нас этого оказалось много
9.3.5 в скриптах (vbscript) базы на postgresql - более жесткий контроль типов например для mssql

Код: Выделить всё

if результат запроса>1
- проходит, а в postgresql только через

Код: Выделить всё

if cint(результат запроса)>1
хотя скрипт один и Option explicit используется - чисто фишка бд Lotsia+postgresql - в 'мультибазе' просто правим все сравнения - чтоб работало и там и там при финальном импорте

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1665
Зарегистрирован: 24 авг 2006, 08:06
Используемое ПО: Lotsia PDM PLUS
Откуда: 55.745578,37.665825

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Александр »

9.3.6 В 'мультибазе' в формах работ при вызове свободных форм из главной по имени в виде строки... если имя формы в верблюжьей нотации например -

Код: Выделить всё

f_FormArrayToData ( this , 'frmContacts')
привести его в нижний регистр

Код: Выделить всё

f_FormArrayToData ( this , Lower ( 'frmContacts' )) 
иначе в LotsiaPDM+PostgreSQL будут или ошибки или формы будут открываться пустыми (спасибо техподдержке за решение такой неочевидной ошибки) - в LotsiaPDM+MSSQL кстати, все нормально и так и так

Софт - LotsiaPDM(4.12-4.40-5.80)<<MSSQL(2000,2005/8)PostgreSQL(16/17)
Уровень администрирования - Альтернативный

Аватара пользователя
Disillusioned
Активный участник
Сообщения: 422
Зарегистрирован: 15 июл 2004, 15:12
Используемое ПО: Lotsia PDM PLUS
Откуда: Подольск
Контактная информация:

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Disillusioned »

Актуальная тема... У нас Sybase и диалект watcom sql, но, смотрю, есть пересечения по ряду вопросов. Пока в начале пути - пишем конвертер с watcom sql на pl/pgsql. Полторы тысячи хранимых процедур на пару сотен тысяч строк кода руками править не вариант. Хорошо, что диалекты достаточно близки по синтаксису, пока обходимся достаточно простыми заменами текста. Но легкой победы, по любому, не ожидается...
Ах и с ними невозможно
И без них никак нельзя
Аватара пользователя
Disillusioned
Активный участник
Сообщения: 422
Зарегистрирован: 15 июл 2004, 15:12
Используемое ПО: Lotsia PDM PLUS
Откуда: Подольск
Контактная информация:

Re: Переезд MSSQL>PostgreSQL (обмен опытом)

Сообщение Disillusioned »

Александр писал(а): 17 июн 2025, 09:25 9.3.6 В 'мультибазе' в формах работ при вызове свободных форм из главной по имени в виде строки... если имя формы в верблюжьей нотации например -

Код: Выделить всё

f_FormArrayToData ( this , 'frmContacts')
привести его в нижний регистр

Код: Выделить всё

f_FormArrayToData ( this , Lower ( 'frmContacts' )) 
иначе в LotsiaPDM+PostgreSQL будут или ошибки или формы будут открываться пустыми (спасибо техподдержке за решение такой неочевидной ошибки) - в LotsiaPDM+MSSQL кстати, все нормально и так и так
Наверное первое, что я услышал про "особенности" ПГ, так это про нетерпимость к символам в верхнем регистре.
Ах и с ними невозможно
И без них никак нельзя
Ответить