Использование ORM вместо работы с чистым SQL

25.11.21

Разработка - Мобильная разработка

Маленькая заметка про небольшой, но полезный релиз Simple UI. Дополнение к основной статье https://infostart.ru/public/1153616/

В Simple UI оффлайн хранение можно организовать в NoSQL или в SQLite. И несмотря на очевидные плюсы NoSQL, старый добрый SQL рано списывать. Быстрые агрегатные функции, быстрый поиск по сложным фильтрам – все это к SQL. Но есть проблемы – для этого нужно знать собственно сам язык SQL (более того, нужно знать конкретную реализацию под конкретную СУБД, а они существенно отличаются) и конструкции для рутинных CRUD – операций в коде довольно громоздкие, особенно если решение большое и таблиц много – нужно все прописывать вручную. Для того придумали ORM (object-relational mapper) – надстройки над SQL которые позволяют:

•    Работать с таблицами СУБД как с объектами – обращаться к атрибутам объекта, наследовать и т.д.
•    Соответственно не нужно знать синтаксиса – ты работаешь с объектами
•    Не задумываться, с какой СУБД работаешь – NoSQL, PostgreSQL, MySQL – ORM работает со всеми, а разработчик работает с единым интерфейсом ORM. Соответственно опять же не нужно знать особенности и читать доки
•    Писать запросы как попало – а ORM сама сделает оптимизацию
•    За счет простоты повышается читаемость кода и проще поддерживать проекты

В общем во всех отношениях чудесная вещь, призванная упростить жизнь разработчика как на маленьких, так и на больших проектах. Скажем так, после перехода на ORM назад к сырому SQL уже не захочется, по крайней мере в CRUD–операциях точно. С SELECT-ами еще можно поспорить. Но дело в том, что ничего не мешает параллельно ORM работать с таблицами напрямую. Хоть средствами самого ORM, хоть другими способами. Т.е. ORM это просто обертка, которая преобразует код работы с объектами в набор SQL-запросов, которые делают транзакции и ничего не мешает обращаться к таблицам другими способами. Т.е., пожалуй что, не найти ни одного аргумента против ее использования.

На самом деле технология давно пустила корни в различных стеках – она есть в Django (собственный ORM), есть SQLAlchemy который используется в множестве именитых проектах и т.д. Для стека SimpleUI+Python+Android я выбрал Pony ORM https://docs.ponyorm.org/firststeps.html . Она ничем не хуже SQL Alchemy или Peewee, но очень простая (что и нужно для Simple) и там есть, например, такие встроенные штуки как работа с типами JSON – т.е. в таблице хранится JSON, а Pony обращается к объекту таблицы и к JSON объекту как к JSON-объекту. Т.е., грубо говоря, можно обращаться через точку.

Работа через ORM напоминает работу в 1С через менеджер объекта (справочника, документа или регистра) с той лишь разницей, что в 1С нет ООП, нет классов и такие вещи, как, например, табличная часть, подчиненная строке табличной части, изобразить напрямую нельзя. 

Вся документация по Pony с примерами есть в вышеприведенной ссылке, от себя я добавил примеры работы с базой через ORM в конфигурации «Примеры с ORM» - там добавление, редактирование, удаление, вложенные объекты и выборки. А также пример, как можно обращаться к «Документам» через ORM, раз уж там с поддержкой JSON в типах такое можно.

Комплект разработчика для версии 7.75 можно скачать в //infostart.ru/public/1153616/

Вкратце изложу на примерах, как использовать Pony в Simple UI. Тут везде используется только код Python – т.е. только оффлайновое выполение кода. Из 1С онлайн такое не сделаешь

1.    Описываем объекты в общем модуле (в Pony они называются «сущностями»). Тут все просто: Required означает обязательный реквизит, Optional – необязательный, PrimaryKey – первичный ключ (по умолчанию создается id, это не нужно декларировать) и Set – это набор (аналог табличной части) который можно включать в себя другие объекты – те объекты какие то другие и т.д.
Типы значений могут быть простые и могут быть другие объекты. Подробнее тут https://docs.ponyorm.org/entities.html

Например, я объявил 2 объекта «Люди» и «Машины». У каждого человека могут быть несколько машин. 

from pony.orm import Database,Required,Set,Json,PrimaryKey,Optional
import datetime

class Person(db.Entity):
        name =  Required(str)
        age = Required(int)
        cars = Set('Car')

class Car(db.Entity):
        make = Required(str)
        model = Required(str)
        owner = Required(Person)

2.    Но эти объекты еще не созданы, потому что это было просто описание – в СУБД ничего не произошло. Да и в какой СУБД? Pony о ней ничего не известно. Поэтому тут же, в объем модуле я пишу что СУБД будет SQLite и указываю путь к ней.

db = Database()
db.bind(provider='sqlite', 
filename='//data/data/ru.travelfood.simple_ui/databases/SimpleWMS', create_db=True)

А также объявляю функцию init с вызовом  generate_mapping  которую надо поставить в ПриЗапуске чтобы каждый раз когда программа запускалась она выполнялась она собсвенно и создает таблицы. После запуска приложения можно проверить и убедиться в консоли что наши таблицы созданы

def init():
    db.generate_mapping(create_tables=True)

 

 
 

3.    Ну и далее работаем уже с объектами Person и Car

Добавить объект (тут и далее они импортируются из общего модуля ui_global)

    with db_session:
        p = ui_global.Person(name=hashMap.get('name'), age=int(hashMap.get('age')))
    Получить объект можно по id:
         with db_session:
        p = ui_global.Person[int(hashMap.get("id"))]
        p.name =hashMap.get('name')
        p.age =int(hashMap.get("age"))

Добавить машину к владельцу

    with db_session:
        ui_global.Car(make=hashMap.get('brand'), model=hashMap.get('model'), owner=ui_global.Person[int(hashMap.get("id"))])
        commit()      

Удалить объект  (предварительно проверив что он есть)
 

    with db_session:
        if ui_global.Person.exists(id=int(hashMap.get("id"))): 
                ui_global.Person[int(hashMap.get("id"))].delete()


Простой запрос с обходом полей

 

query = select(c for c in ui_global.Car if c.owner==ui_global.Person[int(hashMap.get("id"))])
rows=[]
for car in query:
    rows.append({"make":car.make,"model":car.model,"id":car.id})

 

Simple UI ORM Мобильная разработка

См. также

Мобильная разработка Мессенджеры и боты Платформа 1С v8.3 1С:Конвертация данных Платные (руб)

Теперь создать telegram-бота - элементарно. Достаточно просто нарисовать блок-схему телеграм-бота, и он сразу заработает. Это возможно при использовании Графического конструктора телеграм-ботов. Это единственный конструктор ботов для telegram, чье качество и функционал подтверждены фирмой 1С, есть сертификат 1С:Совместимо. Расширение в интерактивном режиме, с помощью блок-схем, позволяет с минимальными трудозатратами создать телеграм-ботов в любой конфигурации, работающей на платформе «1С:Предприятие 8.3».

13200 руб.

27.12.2021    38190    108    161    

201

Мобильная разработка Сканер штрих-кода Терминал сбора данных Управляемые формы Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

Сбор заказов, инвентаризация, проверка ценников, просмотр полной информации об остатках и ценах со смартфона Онлайн - все это содержит в себе решение 1С "Штрихкод-информер" (штрих-код чекер). Отправка данных со смартфона выполняется либо напрямую в открытую форму документа, отсканировав QR-код, либо в общую корзину учетной системы, не подходя к компьютеру. Кассир или оператор сможет просмотреть список присланных данных и загрузить в любую форму, поддерживающую работу с ТСД. Для работы с мобильным приложением требуется опубликовать HTTP-сервис из поставляемого расширения.

3000 руб.

03.12.2018    59286    192    103    

172

Сканер штрих-кода Терминал сбора данных Мобильная разработка Монитор заказов Оптовая торговля Розничная торговля Ценообразование, анализ цен Программист Пользователь Платформа 1С v8.3 Мобильная платформа 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Розничная и сетевая торговля (FMCG) Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Простой мобильный ТСД (терминал сбора данных) сканер для 1С для смартфонов на iOS и Android, не требующий сложных настроек и установки дополнительных программ. Обмен между Вашей 1С и мобильным приложением осуществляется через облачный сервис и расширение конфигурации. Работает с конфигурациями УТ 11, ERP, КА2, Розница 2, Розница 3, УНФ 1.6, УНФ 3.0. Полнофункциональный демо-доступ для своей конфигурации можно запросить в настройках мобильного приложения - все необходимое придет на почту автоматически.

2000 руб.

22.04.2019    97208    586    189    

321

Логистика, склад и ТМЦ Сканер штрих-кода Терминал сбора данных Мобильная разработка Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 Россия Бухгалтерский учет Управленческий учет Платные (руб)

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

3450 руб.

28.04.2023    9466    15    0    

9

Мобильная разработка Платформа 1С v8.3 Конфигурации 1cv8 Финансовые услуги, инвестиции Управленческий учет Платные (руб)

Мобильное приложение и конфигурация 1С для автоматической торговли на бирже через API Тинькофф банка. Достаточно задать настройки, нажать «Пуск», и робот сам торгует ежедневно.

7000 руб.

25.05.2022    4643    1    0    

6

Мобильная разработка WEB-интеграция Программист Мобильная платформа Абонемент ($m)

Экспериментальный релиз и простенький скрипт к нему закрывает потребности в любых видах синхронизации между устройствами Simple и между Simple и бек-системами (например 1С). По сути – это очень простой python-скрипт, который можно запустить на доступной машине, сервере или VPS и он будет связывать клиентские устройства между собой и с 1С или другими бек-системами. В самой платформе появилось для этого множество доработок для поддержки стабильного постоянного соединения, докачки больших файлов и работе в фоне. Дополнение к основной статье https://infostart.ru/1c/tools/1153616/

1 стартмани

23.08.2024    1215    6    informa1555    1    

13

Мобильная разработка Мобильная платформа Абонемент ($m)

В этом релизе собрано много нового из области интерфейса, связи, хранения и важные новые способы управления. Дополнение к основной статье https://infostart.ru/1c/tools/1153616/

1 стартмани

25.06.2024    2603    29    informa1555    0    

33
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user1466751 18 26.11.21 12:44 Сейчас в теме
Добрый день.
В демобазу с примерами будет добавлены рабместа с использованием ORM?
2. informa1555 2715 26.11.21 13:23 Сейчас в теме
(1) Добрый день! Уже добавлены примеры.
3. starik-2005 3087 26.11.21 14:32 Сейчас в теме
4. zhichkin 1524 28.11.21 00:36 Сейчас в теме
Т.е., пожалуй что, не найти ни одного аргумента против ее (ORM - прим. Zhichkin) использования.

Очень спорное утверждение. Приведу лишь только несколько ссылок из их огромного числа, существующих на эту тему:
1. ORM Is an Offensive Anti-Pattern
2. The Vietnam of Computer Science
3. Breaking Free From the ORM: Why Move On ?
5. informa1555 2715 28.11.21 14:31 Сейчас в теме
(4) Я прочитал пост из первой ссылки (тот что написан на ломаном инглише или переведен софтовым переводчиком) и попытался понять аргументацию автора. Что ему не нравится в O/R (точнее как я понял в hibernate, а не в ORM в целом): 1) то что две точки входа? Так это не так. Он работает через объект, у него нет других точек входа, у него один интерфейс. То что данные там усеченные - и что? Они могут быть не усеченные 2) SQL не скрыт - так это реализация Hibernate конкретно такая -там есть HQL, в других ORM не так. например в Pony есть лямбда выражения. То что он дальше предлагает - это его видение, ему так удобно.
Для меня важно 1) скорость разработки 2) простота поддержки и масштабирования - думаю работать с объектами то попроще чем разгребать легайси из кучи SQL запросов. 3) приемлемая производительность. Этот пункт требует конкретных измерений, но я думаю что прямые запросы быстрее. Вопрос насколько это приемлемо. Так как симпл - это платформа для "фронтов" то на фронтах сильно нагружающие запросы не приветствуются, но они есть - например поиск штрихкода по таблице с 50 млн. строк автономно (на ТСД без связи с сервером), поэтому этот вопрос конечно со счетов сбрасывать нельзя но тут все решает практика. Если ORM что то делает за 2мс а прямой SQL за 1 мс, то это конечно победа всухую, только это не важно потому что и 2 и 22 мс это приемлемо. Ох уж мне эти теоретики от айти)) В общем по поводу этой статьи согласен с комментом под ней "Also, the time used to complaint above suggestion or researching the best way to map data fields, are enough for completing 10 more projects on hand , leaving you more personal time with your family."
6. zhichkin 1524 28.11.21 15:26 Сейчас в теме
(5) Я хотел лишь указать на то, что не так всё просто в мире ИТ, а просто - не то же самое, что легко. Статьи по вышеуказанным ссылкам написаны именно практиками с более чем 20-летним стажем. Это не просто фантазийное теоретизирование о сферических конях в вакууме, бороздящих просторы Вселенной.
От себя хотел добавить: взять, например, наш любимый ORM - 1С:Предприятие. Он поддерживает концепцию составных типов данных. Тот, кто занимался оптимизацией производительности 1С уже понял о чём я говорю. И таких "фишек" хватает в любом ORM.
Для тех, кому интересно понять как с этим жить, в самом конце статьи по второй ссылке описаны возможные подходы в использовании ORM.
ELInfinito; +1 Ответить
7. malikov_pro 1324 28.11.21 23:02 Сейчас в теме
(4)
1. и 3. вроде толковые, имеет смысл перевести для развития сообщества (чтобы было понятно что "1С:Предприятие это ORM")
2. тема увязания понятна, но в аналогию с войной нет желания лезть.

(5) "думаю работать с объектами то попроще чем разгребать легайси из кучи SQL запросов" - с точки зрения структурирования данных на уровне кода ORM привлекательна, но дальше либо неоптимально дергаем данные либо начинаем наворачивать запросы (в PHP Symfony это репозитории).

В заголовке статьи не обозначены рамки, из статьи понял что применимость для SQL внутри мобильного приложения. Если придерживаться их то ORM оптимальный выбор (относительно простая схема, нет ограничений к данным).

Если общие рамки, то начинаются проблемы, из ваших статей узнал про PostREST.
При использовании уперся в запись связанных данных (заказ и его ТЧ), попутно решая вопросы аутентификации и разделения данных для пользователей (не увидел что вы рассматривали вопросы консистентности и безопасности).
Дальше уперся в вопрос версионирования схем SQL и миграциями, нашел https://github.com/subzerocloud/postgrest-starter-kit, в котором "Full migration management (migration files are automatically created) through subzero-cli/sqitch/apgdiff". Собираюсь переводить свой проект на subzero, пока ограничение разворачивание на prod через Actions не на AWS.
8. informa1555 2715 29.11.21 07:16 Сейчас в теме
(7) Эта статья несет чисто утилитарную функцию - показать как еще можно работать с SQL для разработчиков мобильных решений на симпле (Simple UI) о чем я и отметил в заголовке, как кстати и статья про поcтгре написанная ранее - она тоже для Simple UI. Т.е. эта статья для стека Simple UI+Python где хранение происходит в SQLite на устройстве. Изначально у меня все примеры были на обычных запросах, но на более менее больших проектах трудно воспринимать код. Поэтому я и написал просто - "используйте Pony" . Честно говоря удивился что статья попала на главную на Инфостарте и вызвала реакцию у людей, не связанных с Simple UI))
Ок, по поводу того что 1С - это ORM. С этим я не полностью согласен. Все таки ORM это штука для объектно-ориентированных языков, коим 1С не является. Т.е. в 1С разработчики безусловно утилизирую классы, но свои декларировать не могут. И например не смогут сделать вот такой пример наследования (выделил жирным родителя):

class Person(db.Entity):
    name = Required(str)

class Student(Person):
    gpa = Optional(Decimal)
    mentor = Optional("Professor")

class Professor(Person):
    degree = Required(str)
    students = Set("Student")
Показать
9. MarryJane 31 16.12.21 18:11 Сейчас в теме
Скажите, а где можно взять последнюю cf
10. informa1555 2715 16.12.21 19:02 Сейчас в теме
(9) Из демо-базы из комплекта разработчика https://infostart.ru/public/1153616/
Оставьте свое сообщение