Ecto para Elixir: Guia para Iniciantes sobre Interações com Banco de Dados
Rafael Andrade

Rafael Andrade @actor-dev

About: I'm Rafael the Actor Dev and I like to talk about Actor Models, Brighter, Elixir & Design Patterns Eu me chamo Rafael o Actor Dev e eu gosto de falar sobre Actor Models, Brighter, Elixir & Design Pat

Location:
London, UK
Joined:
Jan 24, 2025

Ecto para Elixir: Guia para Iniciantes sobre Interações com Banco de Dados

Publish Date: May 9
1 0

Introdução ao Ecto com Elixir: Configuração e Operações Básicas

Durante minha jornada de aprendizado em Elixir, descobri o Ecto, uma poderosa camada de abstração para bancos de dados e gerador de consultas que permite interagir com bancos SQL de forma intuitiva. Embora frequentemente comparado a ORMs como o Entity Framework Core ou o ActiveRecord do Ruby on Rails, o Ecto se diferencia por não rastrear automaticamente estados de entidades, exigindo que os desenvolvedores gerenciem mudanças de forma explícita. Este artigo explora conceitos fundamentais do Ecto, incluindo repositórios, schemas, migrações e operações CRUD. Para recursos avançados, consulte a documentação oficial do Ecto.

O que é o Ecto?

O Ecto é uma camada de abstração para bancos de dados projetada para trabalhar com bancos relacionais como PostgreSQL e MySQL. Ele oferece:

  • Mapeamento de tabelas para structs (via schemas).
  • Geração de consultas com sintaxe segura usando a sintaxe do Elixir.
  • Validação de dados antes da persistência (via changesets).
  • Gerenciamento de migrações com controle de versão.

Por que o Ecto não é um ORM tradicional?

O Ecto evita armadilhas comuns de ORMs tradicionais:

  1. Sem rastreamento automático de estado: Diferente de ORMs, o Ecto não rastreia estados de entidades (ex: campos modificados).
  2. Fluxo de dados explícito: Desenvolvedores devem passar dados manualmente por changesets antes da persistência.
  3. Alinhamento com o paradigma funcional: O Ecto segue o modelo de programação funcional do Elixir, evitando o "impedance mismatch" de mapeamento objeto-relacional.

Requisitos

  • Elixir 1.18+ (ajuste para versões anteriores, se necessário)
  • Adicione as dependências em mix.exs:
{:ecto_sql, "~> 3.0"},  # Ecto  
{:postgrex, ">= 0.0.0"} # Driver para PostgreSQL  
Enter fullscreen mode Exit fullscreen mode

Configuração do Repositório

Um repositório (ou repo) é a interface do Ecto com o banco de dados, semelhante ao DbContext do Entity Framework.

Configuração Manual

  1. Defina um módulo de repositório:
defmodule Friends.Repo do  
  use Ecto.Repo,  
    otp_app: :friend,  
    adapter: Ecto.Adapters.Postgres  
end  
Enter fullscreen mode Exit fullscreen mode
  1. Configure em config/config.exs:
config :friends, Friends.Repo,  
  database: "friends",  
  username: "user",  
  password: "pass",  
  hostname: "localhost"  
Enter fullscreen mode Exit fullscreen mode

Configuração Automática via Mix

Execute:

mix ecto.gen.repo -r Friends.Repo  
Enter fullscreen mode Exit fullscreen mode

Executando o Ecto no Início

Adicione o repositório ao supervisor da aplicação em lib/<app_name>/application.ex:

def start(_type, _args) do  
  children = [Friends.Repo]  
  ...  
end  
Enter fullscreen mode Exit fullscreen mode

Atualize config/config.exs:

config :friends, ecto_repos: [Friends.Repo]  
Enter fullscreen mode Exit fullscreen mode

Criando um Schema

Um schema mapeia uma tabela do banco para uma struct do Elixir. Exemplo de schema Person:

defmodule Friends.Person do  
  use Ecto.Schema  
  import Ecto.Changeset  

  schema "people" do  
    field :first_name, :string  
    field :last_name, :string  
    field :age, :integer  
  end  

  def changeset(person, params \\ %{}) do  
    person  
    |> cast(params, [:first_name, :last_name, :age])  
    |> validate_required([:first_name, :last_name])  
  end  
end  
Enter fullscreen mode Exit fullscreen mode

Migrações

Migrações definem alterações incrementais no esquema do banco.

Migração Manual

Crie um arquivo em priv/repo/migrations/<datetime>_create_people.exs:

defmodule Friends.Repo.Migrations.CreatePeople do  
  use Ecto.Migration  

  def change do  
    create table(:people) do  
      add :first_name, :string  
      add :last_name, :string  
      add :age, :integer  
    end  
  end  
end  
Enter fullscreen mode Exit fullscreen mode

Migração Automática via Mix

Execute:

mix ecto.gen.migration create_people  
Enter fullscreen mode Exit fullscreen mode

Este comando cria um arquivo vazio para edição.

Executando Migrações

mix ecto.create   # Cria o banco de dados  
mix ecto.migrate # Executa as migrações  
Enter fullscreen mode Exit fullscreen mode

Operações CRUD

Create (Criar)

Insira um novo registro:

person = %Friends.Person{first_name: "Alice", last_name: "Smith", age: 30}  
{:ok, inserted_person} = Friends.Repo.insert(person)  
Enter fullscreen mode Exit fullscreen mode

Com validação:

changeset = Friends.Person.changeset(%Friends.Person{}, %{first_name: "Alice"})  
case Friends.Repo.insert(changeset) do  
  {:ok, person} -> # Sucesso  
  {:error, changeset} -> # Trate erros  
end  
Enter fullscreen mode Exit fullscreen mode

Read (Ler)

Busque registros:

# Por ID  
Friends.Repo.get(Friends.Person, 1)  

# Primeiro registro  
Friends.Repo.one(from p in Friends.Person, order_by: [asc: p.id], limit: 1)  

# Todos os registros que atendem a uma condição  
Friends.Repo.all(from p in Friends.Person, where: like(p.first_name, "A%"))  
Enter fullscreen mode Exit fullscreen mode

Update (Atualizar)

Atualize um registro existente:

person = Friends.Repo.get!(Friends.Person, 1)  
changeset = Friends.Person.changeset(person, %{age: 31})  
Friends.Repo.update(changeset)  
Enter fullscreen mode Exit fullscreen mode

Delete (Excluir)

Exclua um registro:

person = Friends.Repo.get!(Friends.Person, 1)  
Friends.Repo.delete(person)  
Enter fullscreen mode Exit fullscreen mode

Conclusão

O Ecto equilibra abstração e controle, oferecendo:

  • Consultas com segurança de tipos: Prevenção de erros em tempo de compilação.
  • Fluxos explícitos: Changesets garantem validação antes da persistência.
  • Suporte da comunidade: Amplamente adotado no ecossistema Elixir.

Embora não seja um ORM tradicional, o design funcional do Ecto evita abstrações problemáticas comuns em mapeadores objeto-relacionais. Para padrões avançados (ex: associações), explore suporte a has_many, belongs_to e many_to_many.

Referências

Comments 0 total

    Add comment