Spec-Zone.ru › Phoenix

Запросы без схем

Исходный код

Большинство запросов в Ecto записываются с использованием схем. Например, чтобы получить все записи из базы данных, можно написать:

MyApp.Repo.all(Post)

В приведённом выше примере Ecto знает все поля и их типы в схеме и преобразует приведённый запрос в следующий:

query =
  from p in Post,
    select: %Post{title: p.title, body: p.body, ...}

MyApp.Repo.all(query)

Хотя в большинстве запросов можно использовать схемы, Ecto также позволяет при необходимости писать обычные запросы без схем.

Например, можно выбрать все нужные поля без дублирования:

from "posts", select: [:title, :body]

Если задан список полей, Ecto автоматически преобразует его в карту или структуру.

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

def update_title(post, new_title) do
  query =
    from "posts",
      where: [id: ^post.id],
      update: [set: [title: ^new_title]]

  MyApp.Repo.update_all(query, [])
end

Конструкция Ecto.Query.update/3 поддерживает четыре команды:

  • :set — задаёт указанному столбцу заданные значения
  • :inc — увеличивает значение указанного столбца на заданное значение
  • :push — добавляет указанное значение в конец столбца-массива
  • :pull — удаляет указанное значение из столбца-массива

Например, можно атомарно увеличить значение столбца с помощью команды :inc, как со схемами, так и без них:

def increment_page_views(post) do
  query =
    from "posts",
      where: [id: ^post.id],
      update: [inc: [page_views: 1]]

  MyApp.Repo.update_all(query, [])
end

Рассмотрим ещё один пример. Представьте, что вы создаёте представление для отчётов. В этом случае может быть контрпродуктивно разбираться, как существующие схемы приложения соотносятся с создаваемым отчётом. Часто проще написать запрос, который возвращает только нужные данные, не пытаясь подогнать их под существующие схемы:

import Ecto.Query

def running_activities(start_at, end_at) do
  query =
    from u in "users",
      join: a in "activities",
      on: a.user_id == u.id,
      where:
        a.start_at > type(^start_at, :naive_datetime) and
          a.end_at < type(^end_at, :naive_datetime),
      group_by: a.user_id,
      select: %{
        user_id: a.user_id,
        interval: a.end_at - a.start_at,
        count: count(u.id)
      }

  MyApp.Repo.all(query)
end

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

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

insert_all, update_all и delete_all

Ecto позволяет выполнять все операции с базой данных без схемы. Одна из доступных функций — Ecto.Repo.insert_all/3. С помощью insert_all разработчики могут за один раз вставить в репозиторий несколько записей, передав адаптеру напрямую источник данных и список полей со значениями:

MyApp.Repo.insert_all(
  "posts",
  [
    [title: "hello", body: "world"],
    [title: "another", body: "post"]
  ]
)

Обновлять и удалять записи также можно без схем с помощью Ecto.Repo.update_all/3 и Ecto.Repo.delete_all/2 соответственно:

# Use the ID to trigger updates
post = from p in "posts", where: [id: ^id]

# Update the title for all matching posts
{1, _} =
  MyApp.Repo.update_all post, set: [title: "new title"]

# Delete all matching posts
{1, _} =
  MyApp.Repo.delete_all post

Нетрудно заметить, что эти операции напрямую соответствуют своим вариантам в SQL и позволяют работать с базой данных без необходимости выполнять все операции через схемы.

← Предыдущая страница Реплики и динамические репозитории
Следующая страница → Фабрики тестовых данных

Пакет Hex Предпросмотр Hex (текущий файл) Просмотреть llms.txt Скачать версию ePub

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

© 2014 Chris McCord
Licensed under the MIT License.
https://ecto.hexdocs.pm/schemaless-queries.html

Spec-Zone.ru

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