View Source ExAws.Dynamo (ExAws.Dynamo v4.2.1)

Operations on the AWS DynamoDB service.

NOTE: When Mix.env in [:test, :dev], Dynamo clients will run by default against DynamoDB local.

basic-usage

Basic usage

defmodule User do
  @derive [ExAws.Dynamo.Encodable]
  defstruct [:email, :name, :age, :admin]
end

alias ExAws.Dynamo

# Create a provisioned users table with a primary key of email [String]
# and 1 unit of read and write capacity
Dynamo.create_table("Users", "email", %{email: :string}, 1, 1)
|> ExAws.request!

user = %User{email: "bubba@foo.com", name: "Bubba", age: 23, admin: false}
# Save the user
Dynamo.put_item("Users", user) |> ExAws.request!

# Retrieve the user by email and decode it as a User struct.
result = Dynamo.get_item("Users", %{email: user.email})
|> ExAws.request!
|> Dynamo.decode_item(as: User)

assert user == result

general-notes

General notes

All options are handled as underscored atoms instead of camelcased binaries as specified in the Dynamo API, e.g. IndexName would be :index_name. Anywhere in the API that requires Dynamo type annotation ({"S":"mystring"}) is handled for you automatically. For example,

ExAws.Dynamo.scan("Users", expression_attribute_values: [api_key: "foo"])

transforms into a query of

%{"ExpressionAttributeValues" => %{api_key: %{"S" => "foo"}}, "TableName" => "Users"}

Consult the function documentation to see precisely which options are handled this way.

If you wish to avoid this kind of automatic behaviour, you are free to specify the types yourself. For example,

ExAws.Dynamo.scan("Users", expression_attribute_values: [api_key: %{"B" => "Treated as binary"}])

becomes

%{"ExpressionAttributeValues" => %{api_key: %{"B" => "Treated as binary"}}, "TableName" => "Users"}

Alternatively, if what's being encoded is a struct, you're always free to implement ExAws.Dynamo.Encodable for that struct.

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations.html

Link to this section Summary

Functions

Batch-get up to 100 items (16 MB total max)

Put or delete up to 25 items (16 MB total max)

Create table with arbitrary options. This provides a superset of the functionality of other create_table variants, allowing the specification of any options as per the create_table_opts/0 type. If no options are specified, defaults will be used as follows

Decode an item returned from Dynamo. This will handle items wrapped in the ordinary get_item response map of %{"Item" => item}.

Delete Table

Describe table

Describe time to live

List tables

A synchronous operation that retrieves multiple items from one or more tables (but not from indexes) in a single account and region

A synchronous write operation that groups up to 25 action requests

Link to this section Types

@type batch_get_item_opts() :: [
  {:return_consumed_capacity, return_consumed_capacity_vals()}
]
Link to this type

batch_write_item_opts()

View Source
@type batch_write_item_opts() :: [
  return_consumed_capacity: return_consumed_capacity_vals(),
  return_item_collection_metrics: return_item_collection_metrics_vals()
]
@type create_table_opts() :: [
  global_indexes: [map()],
  local_indexes: [map()],
  read_capacity: pos_integer(),
  write_capacity: pos_integer(),
  billing_mode: dynamo_billing_types(),
  stream_enabled: boolean(),
  stream_view_type: stream_view_type()
]
@type delete_item_opts() :: [
  condition_expression: binary(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  return_item_collection_metrics: return_item_collection_metrics_vals(),
  return_values: return_values_vals()
]
Link to this type

dynamo_billing_types()

View Source
@type dynamo_billing_types() :: :pay_per_request | :provisioned
@type dynamo_type_names() ::
  :blob
  | :boolean
  | :blob_set
  | :list
  | :map
  | :number_set
  | :null
  | :number
  | :string
  | :string_set
Link to this type

exclusive_start_key_vals()

View Source
@type exclusive_start_key_vals() ::
  [{atom(), binary()}] | %{required(atom()) => binary()}
Link to this type

expression_attribute_names_vals()

View Source
@type expression_attribute_names_vals() :: %{required(binary()) => binary()}
Link to this type

expression_attribute_values_vals()

View Source
@type expression_attribute_values_vals() ::
  [{atom(), ExAws.Dynamo.Encodable.t()}]
  | %{required(atom()) => ExAws.Dynamo.Encodable.t()}
@type get_item() :: [
  consistent_read: boolean(),
  keys: [primary_key()],
  expression_attribute_names: expression_attribute_names_vals(),
  projection_expression: binary()
]
@type get_item_opts() :: [
  consistent_read: boolean(),
  expression_attribute_names: expression_attribute_names_vals(),
  projection_expression: binary(),
  return_consumed_capacity: return_consumed_capacity_vals()
]
@type key_definitions() :: [{atom() | binary(), dynamo_type_names()}, ...]
@type key_schema() :: [{atom() | binary(), :hash | :range}, ...]
@type primary_key() :: [{atom(), binary()}] | %{required(atom()) => binary()}
@type put_item_opts() :: [
  condition_expression: binary(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  return_item_collection_metrics: return_item_collection_metrics_vals(),
  return_values: return_values_vals()
]
@type query_opts() :: [
  consistent_read: boolean(),
  exclusive_start_key: exclusive_start_key_vals(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  filter_expression: binary(),
  index_name: binary(),
  key_condition_expression: binary(),
  limit: pos_integer(),
  projection_expression: binary(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  scan_index_forward: boolean(),
  select: select_vals()
]
Link to this type

return_consumed_capacity_vals()

View Source
@type return_consumed_capacity_vals() :: :none | :total | :indexes
Link to this type

return_item_collection_metrics_vals()

View Source
@type return_item_collection_metrics_vals() :: :size | :none
Link to this type

return_values_on_condition_check_failure_vals()

View Source
@type return_values_on_condition_check_failure_vals() :: :all_old | :none
@type return_values_vals() ::
  :none | :all_old | :updated_old | :all_new | :updated_new
@type scan_opts() :: [
  consistent_read: boolean(),
  exclusive_start_key: exclusive_start_key_vals(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  filter_expression: binary(),
  index_name: binary(),
  limit: pos_integer(),
  projection_expression: binary(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  segment: non_neg_integer(),
  select: select_vals(),
  total_segments: pos_integer()
]
@type select_vals() ::
  :all_attributes | :all_projected_attributes | :specific_attributes | :count
@type stream_view_type() :: :keys_only | :new_image | :old_image | :new_and_old_images
@type table_name() :: binary()
@type transact_get_item() ::
  {table_name :: binary(), primary_key :: primary_key()}
  | {table_name :: binary(), primary_key :: primary_key(),
     transact_get_item_opts()}
Link to this type

transact_get_item_opts()

View Source
@type transact_get_item_opts() :: [
  expression_attribute_names: expression_attribute_names_vals(),
  projection_expression: binary()
]
Link to this type

transact_get_items_opts()

View Source
@type transact_get_items_opts() :: [
  {:return_consumed_capacity, return_consumed_capacity_vals()}
]
Link to this type

transact_standard_item_opts()

View Source
@type transact_standard_item_opts() :: [
  condition_expression: binary(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  return_values_on_condition_check_failure:
    return_values_on_condition_check_failure_vals()
]
Link to this type

transact_update_item_opts()

View Source
@type transact_update_item_opts() :: [
  condition_expression: binary(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  return_values_on_condition_check_failure:
    return_values_on_condition_check_failure_vals(),
  update_expression: binary()
]
@type transact_write_item() ::
  {:condition_check,
   {table_name :: binary(), key :: primary_key(), transact_standard_item_opts()}}
  | {:delete,
     {table_name :: binary(), key :: primary_key(),
      transact_standard_item_opts()}}
  | {:put,
     {table_name :: binary(), item :: map(), transact_standard_item_opts()}}
  | {:update,
     {table_name :: binary(), key :: primary_key(), transact_update_item_opts()}}
Link to this type

transact_write_items_opts()

View Source
@type transact_write_items_opts() :: [
  client_request_token: binary(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  return_item_collection_metrics: return_item_collection_metrics_vals()
]
@type update_item_opts() :: [
  condition_expression: binary(),
  expression_attribute_names: expression_attribute_names_vals(),
  expression_attribute_values: expression_attribute_values_vals(),
  return_consumed_capacity: return_consumed_capacity_vals(),
  return_item_collection_metrics: return_item_collection_metrics_vals(),
  return_values: return_values_vals(),
  update_expression: binary()
]
@type update_table_opts() :: create_table_opts()
@type write_item() :: [
  [{:delete_request, [{:key, primary_key()}]}]
  | [{:put_request, [{:item, map()}]}]
]

Link to this section Functions

Link to this function

batch_get_item(data, opts \\ [])

View Source
@spec batch_get_item(
  %{required(table_name()) => get_item()},
  opts :: batch_get_item_opts()
) ::
  ExAws.Operation.JSON.t()

Batch-get up to 100 items (16 MB total max)

Map of table names to request parameter maps. https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html

Parameters with keys that are automatically annotated with dynamo types are: [:keys]

Dynamo.batch_get_item(%{
  "Users" => [
    consistent_read: true,
    keys: [
      [api_key: "key1"],
      [api_key: "api_key2"]
    ],
    expression_attribute_names: %{"#api_key" => "api_key"},
    projection_expression: "#api_key"
  ],
  "Subscriptions" => %{
    keys: [
      %{id: "id1"}
    ]
  }
})

As you see, you're largely free to use either keyword args or maps in the body. A map is required for the argument itself because the table names are most often binaries, and I refuse to inflict proplists on anyone.

Link to this function

batch_write_item(data, opts \\ [])

View Source
@spec batch_write_item(
  %{required(table_name()) => [write_item()]},
  opts :: batch_write_item_opts()
) ::
  ExAws.Operation.JSON.t()

Put or delete up to 25 items (16 MB total max)

Map of table names to request parameter maps. https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html

Parameters with keys that are automatically annotated with Dynamo types are: [:keys]

Link to this function

create_table(name, key_schema, key_definitions, opts \\ [])

View Source

Create table with arbitrary options. This provides a superset of the functionality of other create_table variants, allowing the specification of any options as per the create_table_opts/0 type. If no options are specified, defaults will be used as follows:

  • billing_mode: :provisioned
  • read_capacity: 10
  • write_capacity: 10
  • stream_enabled: false
Link to this function

create_table(name, primary_key, key_definitions, read_capacity, write_capacity, billing_mode \\ :provisioned)

View Source
@spec create_table(
  table_name :: binary(),
  key_schema :: binary() | atom() | key_schema(),
  key_definitions :: key_definitions(),
  read_capacity :: pos_integer(),
  write_capacity :: pos_integer(),
  billing_mode :: dynamo_billing_types()
) :: ExAws.Operation.JSON.t()

Create table

key_schema can be a simple binary or atom indicating a simple hash key.

billing_mode may be either :provisioned (default) or :pay_per_request. If you are creating a :pay-per-request table, you will still need to provide values for read and write capacities, although they will be ignored - you may consider providing nil in those cases.

Link to this function

create_table(name, key_schema, key_definitions, read_capacity, write_capacity, global_indexes, local_indexes, billing_mode \\ :provisioned)

View Source
@spec create_table(
  table_name :: binary(),
  key_schema :: key_schema(),
  key_definitions :: key_definitions(),
  read_capacity :: pos_integer(),
  write_capacity :: pos_integer(),
  global_indexes :: [map()],
  local_indexes :: [map()],
  billing_mode :: dynamo_billing_types()
) :: ExAws.Operation.JSON.t()

Create table with secondary indices

Each index should follow the format outlined here: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_CreateTable.html

For convenience, the keys in each index map are allowed to be atoms. e.g: "KeySchema" in the aws docs can be key_schema:

Note that both the global_indexes and local_indexes arguments expect a list of such indices.

billing_mode may be either :provisioned (default) or :pay_per_request. If you are creating a :pay-per-request table, you will still need to provide values for read and write capacities, although they will be ignored - you may consider providing nil in those cases.

Examples

secondary_index = [%{
  index_name: "my-global-index",
  key_schema: [%{
    attribute_name: "email",
    key_type: "HASH",
  }],
  provisioned_throughput: %{
    read_capacity_units: 1,
    write_capacity_units: 1,
  },
  projection: %{
    projection_type: "KEYS_ONLY",
  }
}]
create_table("TestUsers", [id: :hash], %{id: :string, email: :string}, 1, 1, secondary_index, [])
Link to this function

decode_item(item, opts \\ [])

View Source
@spec decode_item(map(), [{:as, atom()}]) :: map() | [map()]

Decode an item returned from Dynamo. This will handle items wrapped in the ordinary get_item response map of %{"Item" => item}.

example

Example

Dynamo.get_item("users", %{id: "asdf"})
|> ExAws.request!
|> Dynamo.decode_item(as: User)
Link to this function

delete_item(name, primary_key, opts \\ [])

View Source
@spec delete_item(
  table_name :: table_name(),
  primary_key :: primary_key(),
  opts :: delete_item_opts()
) :: ExAws.Operation.JSON.t()

Delete item in table

@spec delete_table(table :: binary()) :: ExAws.Operation.JSON.t()

Delete Table

@spec describe_table(name :: binary()) :: ExAws.Operation.JSON.t()

Describe table

Link to this function

describe_time_to_live(table)

View Source
@spec describe_time_to_live(table :: binary()) :: ExAws.Operation.JSON.t()

Describe time to live

Link to this function

get_item(name, primary_key, opts \\ [])

View Source
@spec get_item(
  table_name :: table_name(),
  primary_key :: primary_key(),
  opts :: get_item_opts()
) ::
  ExAws.Operation.JSON.t()

Get item from table

@spec list_tables() :: ExAws.Operation.JSON.t()

List tables

Link to this function

put_item(name, record, opts \\ [])

View Source
@spec put_item(table_name :: table_name(), record :: map(), opts :: put_item_opts()) ::
  ExAws.Operation.JSON.t()

Put item in table

@spec query(table_name :: table_name(), opts :: query_opts()) ::
  ExAws.Operation.JSON.t()

Query Table

Please read https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html

Dynamo.query("Users",
  limit: 1,
  expression_attribute_values: [desired_api_key: "adminkey"],
  key_condition_expression: "api_key = :desired_api_key")

Parameters with keys that are automatically annotated with dynamo types are: [:exclusive_start_key, :expression_attribute_names]

@spec scan(table_name :: table_name(), opts :: scan_opts()) ::
  ExAws.Operation.JSON.t()

Scan table

Please read https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html

Dynamo.scan("Users"
  limit: 1,
  expression_attribute_values: [desired_api_key: "adminkey"],
  expression_attribute_names: %{"#asdf" => "api_key"},
  filter_expression: "#asdf = :desired_api_key")

Generally speaking, you won't need to use :expression_attribute_names. It exists to alias a column name if one of the columns you want to search against is a reserved Dynamo word, like Percentile. In this case, it's totally unnecessary as api_key is not a reserved word.

Parameters with keys that are automatically annotated with Dynamo types are: [:exclusive_start_key, :expression_attribute_names]

Link to this function

transact_get_items(items, opts \\ [])

View Source
@spec transact_get_items(items :: [transact_get_item()], transact_get_items_opts()) ::
  ExAws.Operation.JSON.t()

A synchronous operation that retrieves multiple items from one or more tables (but not from indexes) in a single account and region

Link to this function

transact_write_items(items, opts \\ [])

View Source
@spec transact_write_items(
  items :: [transact_write_item()],
  transact_write_items_opts()
) ::
  ExAws.Operation.JSON.t()

A synchronous write operation that groups up to 25 action requests

Link to this function

update_item(table_name, primary_key, update_opts)

View Source
@spec update_item(
  table_name :: table_name(),
  primary_key :: primary_key(),
  opts :: update_item_opts()
) :: ExAws.Operation.JSON.t()

Update item in table

For update_args format see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html

Link to this function

update_table(name, opts)

View Source
@spec update_table(name :: binary(), opts :: update_table_opts() | map()) ::
  ExAws.Operation.JSON.t()

Update Table

Link to this function

update_time_to_live(table, ttl_attribute, enabled)

View Source
@spec update_time_to_live(
  table :: binary(),
  ttl_attribute :: binary(),
  enabled :: boolean()
) ::
  ExAws.Operation.JSON.t()

Update time to live