Spec-Zone.ru › Phoenix

Ecto.Queryable протокол

Исходный код

Преобразует структуру данных в Ecto.Query.

Это используется в Ecto.Repo, а также макросом from. Например, Repo.all ожидает в качестве аргумента любой объект, поддерживающий запросы, поэтому можно написать Repo.all(MySchema) или Repo.all(query). Кроме того, когда вы пишете from ALIAS in QUERYABLE, QUERYABLE принимает любую структуру данных, реализующую Ecto.Queryable.

Этот модуль определяет несколько реализаций по умолчанию. Рассмотрим каждую из них и способы их использования.

Atom

Наиболее распространённый вариант использования этого протокола — преобразование атомов, представляющих модуль Ecto.Schema, в запрос. Это происходит, когда вы пишете:

query = from(p in Person)

Или когда напрямую передаёте схему репозиторию:

Repo.all(Person)

Если вы не знали, модули Elixir — это просто атомы. Эта реализация принимает имя указанного модуля и пытается загрузить связанную с ним схему. Если схема не существует, будет вызвано исключение Protocol.UndefinedError.

BitString

Эта реализация позволяет напрямую указать таблицу, из которой нужно выполнить запрос:

from(
  p in "people",
  select: {p.first_name, p.last_name}
)

Или:

Repo.delete_all("people")

Хотя это довольно просто, для некоторых операций репозитория, таких как Repo.all, требуется выражение select. При запросе к схеме список выбираемых полей определяется автоматически на основе полей схемы, но при прямой передаче таблицы их нужно перечислить явно. Это ограничение подводит нас к следующей реализации!

Tuple

Подобно реализации BitString, эта реализация позволяет указать базовую таблицу, из которой нужно выполнить запрос; однако, кроме того, она позволяет указать используемую схему:

from(p in {"filtered_people", Person})

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

Ecto.Query

Это простая передача без изменений. Ведь любой экземпляр Ecto.Query можно преобразовать в Ecto.Query:

Repo.all(from u in User, where: u.active)

Это также позволяет объединять запросы Ecto: один запрос можно передать в качестве источника другого:

active_users = from u in User, where: u.active
ordered_active_users = from u in active_users, order_by: u.created_at

Ecto.SubQuery

Ecto также позволяет объединять запросы с помощью подзапросов. Представьте, что у вас есть таблица «люди». Теперь представьте, что вы хотите выполнить операцию над людьми с наиболее распространёнными фамилиями. Чтобы получить такой список, можно написать следующее:

sub = from(
  p in Person,
  group_by: p.last_name,
  having: count(p.last_name) > 1,
  select: %{last_name: p.last_name, count: count(p.last_name)}
)

Если теперь вы хотите выполнить с этими данными что-то ещё, например присоединить дополнительные таблицы и выполнить вычисления, это можно сделать так:

from(
  p in subquery(sub),
  # other filtering etc here
)

Обратите внимание, что здесь необходим макрос Ecto.Query.subquery/2, чтобы преобразовать Ecto.Query в экземпляр Ecto.SubQuery. Затем этот протокол оборачивает его в Ecto.Query, используя переданный подзапрос в предложении FROM. Дополнительные сведения см. в разделе Ecto.Query.subquery/2.

Сводка

Типы

t()

Все типы, реализующие этот протокол.

Функции

to_query(data)

Преобразует переданный data в Ecto.Query.

Типы

t()Исходный код

@type t() :: term()

Все типы, реализующие этот протокол.

Функции

to_query(data)Исходный код

Преобразует переданный data в Ecto.Query.

Пакет Hex Предпросмотр Hex Просмотреть llms.txt Скачать версию ePub

Создано с помощью ExDoc (v0.40.2) для языка программирования Elixir

© 2014 Chris McCord
Licensed under the MIT License.
https://ecto.hexdocs.pm/Ecto.Queryable.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API