F6 · the architecture · module 3
Ecto: schemas, changesets & queries
Ecto is Elixir’s database toolkit, and it does its work in three clear pieces. A
schema maps a database table to a plain Elixir struct, so a row is a
%Course{} in your code. A changeset is a pure pipeline that casts and
validates incoming data before any write, carrying its own valid? flag and errors. And
the repo runs composable queries and persists changesets. The discipline that keeps F5 intact
is where Ecto lives: behind the engine’s port — the same
Portal.EventStore behaviour from the F5.09 lab, now backed by its Postgres adapter
— so the domain core still names no database. Ecto is an adapter detail, not a layer the Portal logic
depends on.
This module covers Ecto’s three pieces and the boundary that contains them: schemas and migrations, changesets and validation, and queries and the repo behind the port.
The changeset pipeline
%{title: "Algebra", credits: 4}
cast → validate → constraint all pass — the Repo writes the row.
Three pieces, one adapter
Schema, changeset, and repo divide the work cleanly: the schema describes the shape, the changeset guards the write, and the repo talks to the database. Together they are the implementation of one driven port from F5 — the core asks the port to read or append, and Ecto is how the Postgres adapter answers. Select a piece to see its role.
The Ecto layer · select a piece
piece: Schema
is: a table ↔ a struct
Ecto is not an ORM that hides the database; it is three explicit tools you compose. And because they sit behind the F5 port, swapping the in-memory adapter for Postgres is a config change, not a rewrite of the Portal.
Three deep dives
In order: how migrations and schemas describe a table and its struct, with a Snowflake primary key; how a changeset casts and validates before a write; and how the repo runs queries and persists, kept behind the engine’s port.
%Course{}. The primary key is a Snowflake bigint we mint, not a serial.cast → validate → %Changeset{}: a pure pipeline that guards every write and carries its own errors.Repo calls, kept behind the F5.09 port so the core never names the database.F5.09 · the port
The engine reads and appends through Portal.EventStore, a behaviour with two adapters.
F6.03 · the Postgres adapter
Ecto implements that port for production — schemas, changesets, and queries behind it.
Start with schemas and migrations, then changesets and validation, then queries and the repo. This module follows F6.02 — routing, controllers & plugs — and the next, F6.04, draws the boundary between Phoenix contexts and the F5 facade.
References
Ecto’s three pieces in reference form: the schema, the changeset, the query, and the repo.
Sources
- Ecto — Schema — mapping a table to a struct.
- Ecto — Changeset — cast, validate, and constraints.
- Ecto — Query — the composable query DSL.
- Ecto — Repo — running queries and persisting.