Загрузка данных (Dataloader)

Загрузчик данных Dataloader это универсальная утилита, которая будет использоваться как часть слоя данных вашего приложения для предоставления упрощенного и консистентного API под различные источники данных, такие как базы данных или веб-сервисы, посредством пакетной обработки и кэширования.

Пакетная обработка (Batching)

Пакетная обработка это основная функция DataLoader. Создайте загрузчик, определив функцию пакетной обработки.

from promise import Promise
from promise.dataloader import DataLoader

class UserLoader(DataLoader):
    def batch_load_fn(self, keys):
        # Here we return a promise that will result on the
        # corresponding user for each key in keys
        return Promise.resolve([get_user(id=key) for key in keys])

Функция пакетной обработки принимает список ключей и возвращает Promise, который резолвит список значений.

Затем загрузите значения из загрузчика. DataLoader объединит отдельные загрузки, которые происходят в одном фрейме (выполняется после того, как Promise разрешится), а затем вызовет функцию пакетной обработки со всеми запрошенными ключами.

user_loader = UserLoader()

user_loader.load(1).then(lambda user: user_loader.load(user.best_friend_id))

user_loader.load(2).then(lambda user: user_loader.load(user.best_friend_id))

Наивное приложение может запросить сервер 4 раза , но с DataLoader данное приложение сделает максимум 2 запроса.

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

Использование с Graphene

DataLoader хорошо сочетается с Graphene / GraphQL.

Поля GraphQL спроектированы для автономных(stand-alone) функций. А без механизма кэширования или пакетной обработки наивный сервер GraphQL будет генерировать новые запросы к базе данных каждый раз при резолве поля.

Рассмотрим следующий запрос GraphQL:

{
  me {
    name
    bestFriend {
      name
    }
    friends(first: 5) {
      name
      bestFriend {
        name
      }
    }
  }
}

Если каждый из me,bestFriend и friends запросит сервер, то получится 13 запросов к базе данных.

При использовании DataLoader, мы могли бы определить тип User , используя предыдущий пример, более компактно и с не более, чем 4 запросами к базе данных, а то и меньше, если использовать кеширования.

class User(graphene.ObjectType):
    name = graphene.String()
    best_friend = graphene.Field(lambda: User)
    friends = graphene.List(lambda: User)

    def resolve_best_friend(self, info):
        return user_loader.load(self.best_friend_id)

    def resolve_friends(self, info):
        return user_loader.load_many(self.friend_ids)

results matching ""

    No results matching ""