View Source Getting started
A complete, minimal walkthrough: local DynamoDB, a repo, a schema, CRUD.
1. Run DynamoDB Local
docker run -p 8000:8000 amazon/dynamodb-local
2. Add the dependency and a repo
# mix.exs
{:dynamo, github: "bmalum/dynamo"}
# lib/my_app/dynamo.ex
defmodule MyApp.Dynamo do
use Dynamo.Repo, otp_app: :my_app
end
# config/dev.exs
config :my_app, MyApp.Dynamo,
region: "eu-central-1",
endpoint: "http://localhost:8000",
access_key_id: "local",
secret_access_key: "local"
# lib/my_app/application.ex
children = [MyApp.Dynamo]3. Define a schema
defmodule MyApp.Note do
use Dynamo.Schema
item do
table "notes"
field :owner, :string, partition_key: true
field :created_at, :utc_datetime, sort_key: true
field :title, :string
field :body, :string
field :tags, :string_set
field :pinned, :boolean, default: false
end
endKeys are generated for you: pk = "note#<owner>", sk = "<created_at ISO 8601>".
4. Create the table from the schema
mix dynamo.create_table --schema MyApp.Note --repo MyApp.Dynamo
5. Use it
alias MyApp.{Dynamo, Note}
note = %Note{owner: "alice", created_at: DateTime.utc_now(), title: "Hello", tags: MapSet.new(["intro"])}
{:ok, note} = Dynamo.put(note)
{:ok, ^note} = Dynamo.get(%Note{owner: "alice", created_at: note.created_at})
{:ok, nil} = Dynamo.update(note, pinned: true, tags: {:add, MapSet.new(["important"])})
{:ok, page} = Dynamo.query(%Note{owner: "alice"}, descending: true, limit: 20)
Enum.map(page.items, & &1.title)
{:ok, nil} = Dynamo.delete(note)Every call returns {:ok, _} | {:error, %Dynamo.Error{}}; use the ! variants
(put!, get!, …) when you'd rather raise.
6. Handle errors
case Dynamo.put(note, condition: "attribute_not_exists(pk)") do
{:ok, note} -> {:ok, note}
{:error, %Dynamo.Error{type: :conditional_check_failed}} -> {:error, :already_exists}
{:error, %Dynamo.Error{} = e} -> raise e
endNext
- Data modelling – composite keys, GSIs, single-table design
- Streaming & batches
- Testing
- Agents.md – patterns and anti-patterns