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

Здесь обсуждаем систему TDM/PDM/Workflow Lotsia PDM PLUS (PartY PLUS).
Ответить
Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Уровень администрирования - Альтернативный

Аватара пользователя
Александр
Активный участник
Сообщения: 1664
Зарегистрирован: 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)
Уровень администрирования - Альтернативный

Ответить