Defines a DynamoDB item schema with typed fields, keys and indexes.
defmodule MyApp.Order do
use Dynamo.Schema
item do
table "app_data"
entity_name "order" # prefix used in generated keys (default: module basename)
field :user_id, :string, partition_key: true
field :placed_at, :utc_datetime, sort_key: true
field :order_id, :string, sort_key: true
field :total, :decimal
field :status, :string, default: "pending"
field :tags, :string_set
global_secondary_index "StatusIndex", partition_key: :status, sort_key: :placed_at
end
end
Fields
field name, type \\ :string, opts. Types are the built-ins listed in
Dynamo.Type or a module implementing Dynamo.Type. Options:
:default – struct default:partition_key / :sort_key – include this field in the composite key
(in declaration order); alternatively use partition_key [...] /
sort_key [...].:required – dump/1 returns an error when the value is nil
Key generation
The table's partition/sort key attributes are named by the partition_key_name
/ sort_key_name options (default "pk" / "sk"). Their values are built by
joining the dumped, stringified key field values with key_separator (default
"#"):
pk = "<entity_name><sep><f1><sep><f2>…"
sk = "<f1><sep><f2>…" (with `prefix_sort_key: true`: "<name1><sep><v1><sep>…")
Every partition-key field must be non-nil – a nil produces a
{:error, %Dynamo.Error{type: :validation_error}}. Sort-key fields may be
partially populated: generation stops at the first nil, which yields a
prefix usable with begins_with queries. Separator characters inside key
values are rejected so keys always round-trip.
Set raw_keys: true to use the first partition/sort key field as is
(no entity prefix, no joining) – for tables not designed around this
library. In that mode the key attribute names default to the field names.
Options (to use Dynamo.Schema)
:partition_key_name, :sort_key_name – attribute names (default "pk"/"sk"):key_separator – default "#":prefix_sort_key – default false:raw_keys – default false:omit_nil – omit nil fields from written items (default true)
Embedded schemas
A schema module can be used as a field type. Declare it with
use Dynamo.Schema, embedded: true (no table, keys or indexes) and nest it
directly or inside a typed list:
defmodule MyApp.Address do
use Dynamo.Schema, embedded: true
item do
field :street, :string
field :city, :string
field :geo, {:list, :float}
end
end
field :address, MyApp.Address
field :previous_addresses, {:list, MyApp.Address}
Embedded values round-trip with full typing (dates stay dates, decimals stay
decimals). Any table schema can also be embedded; its key attributes are not
included when nested.
Generated functions
__schema__/1 (:table, :fields, :field_types, :partition_key,
:sort_key, :indexes, :vector_indexes, :options, :entity_name),
__schema__/2 ({:type, field}, {:index, name}, {:vector_index, name}).