[ON] Опубликована библиотека urm для Python

Обсуждение новостей, соответствующих тематике форума

Модератор: Модераторы разделов

Аватара пользователя
rssbot
Бот
Сообщения: 6005
ОС: gnu/linux

[ON] Опубликована библиотека urm для Python

Сообщение rssbot »

Доступна библиотека urm.py с реализацией URM (UnRelational Mapper) для языка Python. Проект может оказаться полезным, когда требуется сохранить какие-нибудь данные не в реляционной базе данных, а в нереляционном хранилище, таком как файловая система, архив, облачное хранилище, NoSQL-база.

Примеры библиотек, в которых необходимы подобные манипуляции:
  • Библиотека UniGrammarRuntime должна уметь читать с диска несколько вариантов (сгенерированных разными генераторами, поддержка которых реализована в UniGrammar в виде бэкендов) парсера для одной и той же грамматики. Парсер может состоять либо из одного файла (файл грамматики в DSL-виде, для parsimonious и tatsu), либо из нескольких (лексер + парсер в транспилированном виде (ANTLR4, CoCo/Py), или 1 файл с транспилированным кодом + 1 файл с байт-кодом (parglare), или, если грамматика модульная, то все модули (пока не реализовано в UniGrammar), причём раскладка по диску должна быть такова, чтобы корректно импортировалось ). Также желательно хранить результаты измерений их производительности. Пример 1, пример 2.
  • В артефактах библиотеки AutoXGBoost необходимо хранить пары файлов, один из которых - модель в одном из поддерживаемых форматов (а их на данный момент 3 - бинарный, транспилированный в AST python с помощью pyxgboost (можно проводить inference без установленного xgboost) и json), а второй - информация о колонках, необходимая для правильного проведения inference и прочие метаданные. И ещё есть файл с гиперпараметрами, который имеет решающее значение при повторной тренировке модели. Ещё планируется добавить туда LightGBM и CatBoost и конвертацию между форматами моделей.


В описанных примерах есть общее:
  • Данные имеют смысл как файлы. Их можно вырвать из контейнера и использовать без него. Но это будет неудобно - контейнер предоставляет дополнительные данные для унифицирующей обвязки.
  • Для гибкости требуется хранить дополнительную информацию. Эта информация должна быть связана с файлами, а хранилище у нас нереляционное.
  • Дополнительную информацию приходится серилизовывать. Нет бесплатного лэнча, есть разные форматы сериализации с разными достоинствами и недостатками. Например YAML красиво выглядит, JSON компактнее и при этом совместимее, бинарные форматы по типу JSON ещё компактнее и не нуждаются в "спасении" строк. Нужно иметь свободу выбирать тот формат, какой наиболее подходит для конкретной задачи. И легко переключать, при изменении требований.
  • Не всегда можно контролировать раскладку файлов. В архитектуру сторонних программ могут быть встроены предположения о том, как файлы лежат на диске. Например если файлы - модули какого-либо ЯП, то импортируемые модули должны лежать относительно импортирующих по известным путям. Можно извратиться с загрузчиками, это приведёт к проблемам (для отладки которых пришлось даже разработать FrozenTable).


Соответственно, имеется 3 критерия:
  • явно-неявно - понятность при взгляде на код, возможность наличия не очевидного с первого взгляда для человека не знакомого с работой системы поведения и необходимость разбираться в системе;
  • легко-трудоёмко - затраты труда и времени на написание и сопровождение;
  • гибко-негибко - будем ли реализовывать всё многообразие.


с предпочтением "явно, легко, гибко", и треугольник "выбери два":
  • явно, легко, негибко - выбрать и написать 1 вариант вручную полностью;
  • явно, трудоёмко, гибко - написать весь код вручную, а потом удалить весь этот код, потому что поддерживать и отлаживать такое нет никакого желания;
  • неявно, легко, гибко - использовать композицию.


В некоторых случаях может быть целесообразно выбрать третий вариант, особенно если писать код вручную не надо, а нужно только освоить готовую библиотеку - urm.py. urm - значит UnRelational Mapper, созвучно с ORM.

Сначала определимся с хранением и сериализацией. И то, и другое инкапсулировано в библиотеку. Всё тривиально: есть интерфейс и несколько классов, один метод распаковывает и парсит, другой сериализует и жмёт, и можно объединять в конвейеры "распаковать из LZMA2 -> декодировать в UTF-8 -> распарсить JSON" (и в обратную сторону тоже работает). Кроме urm эта библиотека используется в Cache.py.

Набор частей данных, связанных друг с другом, хранимый в хранилище, назовём bundle ("свёрток"). Ему соответствует класс ProtoBundle (который основан на метаклассе, создающем нужные дескрипторы), от которого нужно унаследовать свой класс. А в нём есть дескрипторы, получая и устанавливая значения в которые мы читаем/пишем в хранилище.

Хранилищ 2 вида, "горячие" и "холодные", холодные для хранения, горячие - для кеширования. Пример холодного хранилища: файл на диске, хранящий данные, сериализованные конкретной схемой сериализации. Пример горячего хранилища - префиксное дерево.

2 вида свойств: 0-мерные (скалярные) и многомерные. К скалярным обращаться нужно через само свойство, к многомерным - через оператор [].

Между дескриптором, свёртком и хранилищами у нас располагается стратегия. Стратегии две:
  • холодная - читает и пишет в холодное хранилище незамедлительно;
  • кешированная - читает из кеша, если кеш пуст - из холодного хранилища, при установке значения пишет в кеш, запись в холодное хранилище производится только тогда, когда вызывается `save` у "свёртка". Есть возможность вызвать `save` для отдельного свойства.


Стратегии параметризуются просто отображателями (Mapper). Просто отображатели бывают холодными (ColdMapper) и горячими (HotMapper). Каждый отображатель - это как минимум пара связанных объектов:
  • отображатель ключей, преобразующий "ключи", родные для холодного хранилища, в ключи, удобные для доступа в приложении (используются в горячем хранилище).
  • хранитель, сохраняющий данные в холодные и горячие хранилища.


Холодный отображатель получает ещё конвейер преобразователей. Горячий, соответственно, не получает, так как горячее хранит данные в формате, удобном для хранения.

Для выражения отношений между хранимыми сущностями через Dynamic задаётся путь по именам свойств с корнем в объекте-"свёртке". В остальных классах присутствует логика, проверяющая, является ли параметр или его компонент Dynamic, и если является - проходящая по указанному в нём пути и использующее полученное значение.


Источник: https://www.opennet.ru/opennews/art.shtml?num=54400
(opennet.ru, мини-новости)
Последний раз редактировалось rssbot 14.01.2021 12:21, всего редактировалось 1 раз.
Причина: Updated upstream
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 17910
Статус: grammatikführer
ОС: Debian GNU/Linux

Re: [ON] Опубликована библиотека urm для Python

Сообщение Bizdelnick »

rssbot писал(а):
14.01.2021 09:30
Дополнительную информацию приходится серилизовывать.
Ну пущай себе серилизовывает Коляныч, шо уж там. Куды ему деваться, коли
rssbot писал(а):
14.01.2021 09:30
Нет бесплатного лэнча
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали: