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

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
14-Янв-2021 12:30

Доступна библиотека 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, и если является - проходящая по указанному в нём пути и использующее полученное значение.
===========
Источник:
OpenNet.RU
===========

Похожие новости: Теги для поиска: #_urm, #_python
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 12:39
Часовой пояс: UTC + 5