Глава 1 | Зачем беспокоиться?
Глава 2 | Изучение основ эликсира
Глава 3 | Введение в Phoenix
Глава 4 | Реализация React

Сфера действия этой главы

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

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

SQL против NoSQL

Изучая React, вы, вероятно, слышали о двух технологиях создания базы данных для вашего приложения: Firebase и MongoDB.

И Firebase, и MongoDB известны как базы данных NoSQL. Обе эти базы данных хранят данные как объекты JSON внутри. Данные также могут быть отправлены через запрос в виде объекта JSON.

Вот внутренний взгляд на базу данных MongoDB:

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

Однако база данных NoSQL (возможно) не обеспечивает лучший способ хранения и запроса данных. Причина в том, что базы данных не реляционные.

Базы данных SQL (язык структурированных запросов) являются реляционными. Вместо хранения данных в объектах JSON они хранятся в таблицах. Таблица состоит из столбцов и строк. Строка содержит одну запись, а столбец содержит значения определенных атрибутов.

Давайте посмотрим на этот пример:

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

Итак, как же реляционные базы данных SQL? Давайте посмотрим на другой пример:

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

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

На мой взгляд, SQL-запросы очень удобочитаемы и легко выполняются. Они также существуют уже давно и доказали свою успешность. По этой причине я просто рекомендую вам просмотреть эту шпаргалку по SQL, чтобы понять, как она работает. Я все же найду время, чтобы объяснить все вопросы, которые мы делаем в этой книге. А пока я просто хочу, чтобы вы поняли разницу между SQL и NoSQL и возможные преимущества.

Введение в PostgreSQL

Почему PostgreSQL?

В этой книге мы будем работать с технологией баз данных SQL под названием PostgreSQL.

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

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

Начиная

При работе с Node.js и MongoDB (как я уже писал здесь) вы можете использовать такой инструмент, как Mongoose, чтобы иметь возможность взаимодействовать с базой данных MongoDB. Phoenix поставляется с инструментом в экосистеме Elixir под названием Ecto, который позволяет взаимодействовать с PostgreSQL, MySQL, SQLite 3m и MongoDB. Другими словами, это позволит нам общаться с различными типами баз данных, чтобы мы могли выполнять операции создания, чтения, обновления и удаления (CRUD). Phoenix по умолчанию поставляется с PostgreSQL.

Официальная документация Phoenix также содержит некоторые полезные определения терминологии Ecto, которые мы распаковываем более подробно позже:

Репо - репозиторий представляет собой соединение с отдельной базой данных. Каждая операция с базой данных выполняется через репозиторий.

Модель - модели - это наши определения данных. Они определяют имена таблиц и полей, а также тип каждого поля. Модели также определяют ассоциации - отношения между моделями.

Запрос. Запросы связывают и модели, и репозитории вместе, позволяя нам элегантно извлекать данные из репозитория и передавать их в сами модели.

Набор изменений - наборы изменений объявляют преобразования, которые нам необходимо выполнить с данными нашей модели, прежде чем наше приложение сможет их использовать. К ним относятся приведение типов, проверки и многое другое.

Прежде чем мы начнем новый проект Phoenix, вам необходимо установить PostgreSQL. Если вы используете Mac, я настоятельно рекомендую использовать этот установщик. Это позволит вам с легкостью установить, настроить и запустить сервер PostgreSQL через графический интерфейс.

Для управления базами данных PostgreSQL через графический интерфейс я рекомендую pgAdmin или Postico. В этой книге мы будем использовать pgAdmin, поскольку он кроссплатформенный. Скачайте его.

Однако в этой главе pgAdmin нам не понадобится. В Phoenix на самом деле есть хороший генератор, который определит новую таблицу в нашей базе данных и заполнит шаблоны (а также представление и контроллер как средства для достижения этого), который покажет нам содержимое таблицы и позволит нам выполнять операции CRUD для Это. В следующей главе мы изменим наш подход и воспользуемся pgAdmin.

Давайте продолжим и создадим новый проект под названием phoenix_curated_list:

mix phoenix.new phoenix_curated_list
cd phoenix_curated_list

Этот проект будет использоваться только для визуализации тщательно подобранного списка сообщений в блоге с использованием данных из базы данных PostgreSQL.

Откройте проект в любом редакторе кода.

Если мы зайдем в config / dev.exs, мы увидим конфигурации для PostgreSQL внизу:

config :phoenix_curated_list, PhoenixCuratedList.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "phoenix_curated_list_dev",
  hostname: "localhost",
  pool_size: 10

Примечание. dev.exs - это конфигурация для среды разработки, а prod.exs - для производственной среды. Общая конфигурация происходит в config.exs.

По умолчанию PostgreSQL устанавливает суперпользователя с именем пользователя и паролем postgres . Если у вас нет такой настройки, вы можете сделать это, запустив:

psql postrgres
CREATE USER postgres;
ALTER USER postgres PASSWORD 'postgres';
ALTER USER postgres WITH SUPERUSER;

По умолчанию порт для PostgreSQL - 5432 и не указан в конфигурации. Лично я использую порт 5431, поэтому моя конфигурация будет выглядеть так:

# Configure your database
config :phoenix_curated_list, PhoenixCuratedList.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "phoenix_curated_list_dev",
  hostname: "localhost",
  pool_size: 10,
  port: 5431

В приведенном выше коде вы увидите PhoenixCuratedList.Repo. Ранее упоминалось, что репо - это соединение с базой данных, с помощью которого мы можем выполнять операции / взаимодействия с базой данных. Phoenix уже настроил репо, просто используя существующий модуль с именем Ecto.Repo, как видно из следующего кода (lib / phoenix_curated_list / repo.ex):

defmodule PhoenixCuratedList.Repo do
  use Ecto.Repo, otp_app: :phoenix_curated_list
end

Это репо также было включено в конфигурацию, находящуюся в config / config.ex и config / dev.ex.

Здесь важно вмешаться и объяснить, что я просто показываю вам эту информацию о нашем репо, чтобы вы знали, что это такое и откуда оно пришло. Опять же, это просто соединение с нашей базой данных, с помощью которого мы можем выполнять операции с нашей базой данных. Если вас интересуют неловкие подробности этого, вы можете проверить документацию Ecto.Repo.

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

mix ecto.create

Это создаст базу данных с именем phoenix_curated_list_dev, как мы указали в нашей конфигурации в config / dev.ex:

# Configure your database
config :phoenix_curated_list, PhoenixCuratedList.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "phoenix_curated_list_dev",
  hostname: "localhost",
  pool_size: 10,
  port: 5431

Если мы запустим наш сервер Phoenix с помощью mix phoenix.server, мы увидим, что раздражающие сообщения об ошибках в командной строке, которые использовались ранее, прекратились.

Ok. У нас есть база данных, настроенная для нашего проекта Phoenix. Что теперь?

Нам нужно создать модель, которая может быть определена как определение данных таблицы, поля (столбцов) и типов полей. Это было бы эквивалентно определению коллекции, ее полей и типов полей в MongoDB.

У Phoenix есть удобный генератор моделей, который делает за нас всю тяжелую работу. Это создаст для нас модель. С помощью всего лишь нескольких дополнительных действий мы можем использовать определения данных в нашей модели для создания таблицы в нашей базе данных. Генератор также предоставит шаблоны, с помощью которых мы можем создавать, читать, обновлять и удалять операции с таблицей.

Во-первых, давайте посмотрим, какой стол мы в конечном итоге захотим.

Нам нужна таблица с названием Блоги со следующими полями:

Blogs Table
____________
    
    title | subtitle | image | link | author
1
2
3
...

Нам также нужно знать типы данных, которые могут быть выражены с помощью атомов (обратите внимание, что идентификатор будет сгенерирован автоматически, поэтому он опускается):

title :string 
subtitle :string 
image :string 
link :string 
author :string

Давайте воспользуемся генератором phoenix.gen.html и укажем, что нам нужна таблица с именем Blogs, к которой можно получить доступ по пути / blogs, содержащему поля, показанные выше:

mix phoenix.gen.html Blogs blogs title:string subtitle:string image:string link:string author:string

В соответствии с запросом в командной строке нам нужно поместить следующий код в наш файл router.ex:

scope "/", PhoenixCuratedList do
  pipe_through :browser # Use the default browser stack
  get "/", PageController, :index
  resources "/blogs", BlogsController
end

Это позволит нам видеть нашу таблицу и выполнять операции CRUD с помощью сгенерированных шаблонов по пути / blogs.

Если мы откроем сгенерированный код модели в web / models / blogs.ex, мы увидим, что была сгенерирована следующая схема, определяющая таблицы, поля и типы полей:

schema "blogs" do
  field :title, :string
  field :subtitle, :string
  field :image, :string
  field :link, :string
  field :author, :string
timestamps()
end

В учебных целях вот снимок нашей текущей базы данных, полученный с помощью Postico:

Обычно здесь появляются таблицы в нашей базе данных. Однако ничего нет.

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

В Phoenix мы делаем это с помощью миграции. Слово «миграция» можно рассматривать как выражение действия по перемещению таблицы в нашу базу данных с использованием определений полей, указанных в схеме в нашей модели.

Итак, как нам выполнить миграцию?

Как вы, возможно, догадались, учитывая тенденцию, Phoenix автоматически генерирует файл миграции, который после выполнения создаст нашу таблицу в соответствии с нашей схемой. Код, создающий таблицу, находится в этом файле, расположенном по адресу priv / repo / migrations / * timestamp * _create_blogs.exs:

def change do
    create table(:blogs) do
      add :title, :string
      add :subtitle, :string
      add :image, :string
      add :link, :string
      add :author, :string
      timestamps()
    end
end

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

defmodule PhoenixCuratedList.Repo.Migrations.CreateBlogs

Чтобы запустить это, мы можем использовать следующую команду:

mix ecto.migrate

С помощью Postico я покажу вам, как сейчас выглядит наша база данных:

Созданы две таблицы. Как и ожидалось, у нас есть таблица blogs и еще одна таблица с именем schema_migrations, которая просто регистрирует метаданные о наших миграциях:

Таблица blogs выглядит так, как мы указали:

Теперь, если вы перейдете на http: // localhost: 4000 / blogs, вы увидите шаблон, который показывает нам таблицу blogs:

Мы можем щелкнуть ссылку «Новые блоги», которая приведет нас к другому шаблону с формой для добавления строки:

Вставьте блог самостоятельно и нажмите "Отправить".

Мы вернулись к полному виду нашей таблицы с добавленной новой строкой:

Мы можем нажимать кнопки справа, чтобы показать, отредактировать или удалить эту строку.

В образовательных целях я покажу этот снимок через Postico, чтобы убедиться, что в нашу таблицу действительно добавлена ​​строка:

Woot woot! Мы создали нашу первую базу данных PostgreSQL, создали таблицу и вставили строку с помощью Phoenix.

Окончательный код

Доступно на GitHub.

Заключительные мысли

Использование генератора Phoenix было начальным способом создания модели, выполнения миграции и выполнения операций CRUD с новой таблицей в нашей базе данных. Это не то, что мы собираемся использовать в будущем, поэтому я не объяснил многие файлы, которые были созданы.

В реальном сценарии мы хотим иметь службу API, чтобы мы могли выполнять операции CRUD через HTTP-запросы из нашего приложения React. Один из сгенерированных файлов, который я не распаковывал, на самом деле делал это, однако мы захотим сделать это программно. Это позволит нам не только познакомиться с этими новыми темами о взаимодействии PostgreSQL с Phoenix (как мы были в этой главе), но и сохранить их. Хотя это означает отказ от использования генератора и, следовательно, шаблонов для просмотра таблиц и выполнения операций CRUD, мы можем сделать это через pgAdmin, как я упоминал ранее.

Приготовься. В следующей главе мы поговорим о полной разработке React с Phoenix.

Глава 6

Глава 6 теперь доступна.

Подпишитесь на уведомления

Получайте уведомления о выходе каждой главы.

С уважением,
Майк Манджаларди
Основатель Coding Artist