TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Python

3 Jan 2025, 23:13

Open in Telegram Share Report

Forward from: Советы разработчикам (python и не только)
Паттерны работы с базами данных

В большинстве проектов мы храним какие-то данные. Для этого используются разные виды баз данных: реляционные, nosql или даже специализированные HTTP API. Такие хранилища имеют специфическое API, которое мы обычно хотим скрыть от основного кода за некоторой абстракцией. Вот стандартные варианты, описанные, в частности, Мартином Фаулером.

Первая группа паттернов работы с БД - отделяющие реализацию операций с хранилищем от данных. Благодаря такому разделению, мы можем построить несколько реализаций шлюза, возвращающих однотипные структуры (например, для заглушек на время тестирования или использования нескольких источников данных). Обратите внимание, что в паттернах этой группы мы можем полностью скрыть детали организации хранилища.

DAO - наиболее простой вариант, он представляет собой достаточно тупой класс, который просто выполняет операции с хранилищем и возвращает данные в том или ином виде. Он не должен содержать какого-то своего состояния (будь то кэши или IdentityMap). Он получает и возвращает только данные в виде неких абстрактных RecordSet или простых DTO, то есть структур, не содержащих логики. Плюсы такого паттерна: простота реализации, возможность точечного тюнинга запросов. Паттерн описан в "Core J2EE Patterns", а у Фаулера встречается очень близкое описание под именем Table Data Gateway.

Data Mapper - в отличие от DAO занимается не просто передачей данных, а двусторонней синхронизацией моделей бизнес логики с хранилищем. То есть он может получать какие-то сущности и потом сохранять их обратно. Внутри он может содержать IdentityMap для исключения дублей модели с одним identity или создания лишних запросов на загрузку. Каждый маппер работает с моделью определенного типа, но в случае составных моделей он иногда может обращаться к другим мапперам (например, при использовании select-in load). При использовании Unit Of Work, тот обращается именно к мапперу для сохранения данных.

Repository - фактически вариант Data Mapper, предназначенный для работы с корневыми сущностями. Для прикладной бизнес логики репозиторий выглядит как коллекция, содержащая корни агрегатов. Он может использоваться для получения полиморфных моделей, а также может возвращать некоторую сводно-статистическую информацию (например, количество элементов или сумму полей) или даже выполнять какие-то расчеты, не выходящие за пределы общей компетенции хранилища данных. Это основной паттерн при использовании богатых доменных моделей. Паттерн описан у Эрика Эванса, а у Фаулера встречаются некоторые варианты его реализации.

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

Raw Data Gateway - предлагает каждой строке таблицы поставить в соответствие экземпляр класса. Мы получаем отдельный класс Finder для загрузки строк и собственно класс шлюза строки, который предоставляет доступ к загруженным данным и обладает методами сохранения себя в БД.

Active Record - вариант RDG, но содержащий бизнес логику. По факту, мы имеем богатые доменные модели не абстрагированные от хранилища. Часто методы загрузки данных реализованы просто как static-методы в этом же классе вместо выделения отдельного Finder.

Строит отметить, что многие ORM в Python реализуют Active Record и активно используют при этом неявный контроль соединений и транзакций. В отличие от них SQLAlchemy реализует паттерн Data Mapper и может дать больший уровень абстракции над хранилищем (обратите внимание на подход с map_imperatively).

Дополнительные материалы:
• http://www.corej2eepatterns.com/Patterns2ndEd/DataAccessObject.htm
• https://martinfowler.com/eaaCatalog/identityMap.html
• https://docs.sqlalchemy.org/en/20/orm/dataclasses.html#applying-orm-mappings-to-an-existing-dataclass-legacy-dataclass-use
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot