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
end

Keys 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
end

Next