DynamoDB Dynomite Model Typecasting
Important: These docs are for the outdated Jets 5 versions and below. For the latest Jets docs: docs.rubyonjets.com
By default, Dynomite uses aws-sdk-dynamodb to typecast by inferring the type from the value itself. Dynomite can also do some additional typecasting on top of the built-in aws-sdk-dynamodb typecasting.
The aws-sdk-dynamodb typecasting is based on inference of the value itself. For example, if you save a Ruby float
value, it’s typecasted by aws-sdk-dynamodb to a DynamoDB number
. If you save a Ruby string
value, it’s saved as a DynamoDB string
. See: github aws-sdk-dynamodb/attribute_value.rb. It’s all handled transparently for you. Whatever data-type value that’s stored is returned later.
Additional Typecasting
Dynomite performs additional typecasting for:
- boolean: Dynomite typecasts
type: :boolean
for these values. These values[false, 'false', 'FALSE', 0, '0', 'f', 'F', 'off', 'OFF']
are falsey. All other values are truthy. It also provides an extra boolean?
method when you set thetype: :boolean
. IE:published?
. This method does run a!!
to ensure it returns a Boolean. - infer: Dynomite does not perform typecasting itself. Instead, it uses aws-sdk-dynamodb to handle the typecasting via inference of the value itself. This allows you to save Array, Set, and Map “types”. This is the default_field_type when you do not specific a type in the model field declartion.
- integer: Dynomite typecasts
type: :integer
with a.to_i
. Internally, it’s still stored as a native DynamoDBnumber
. However, seeing Ruby float numbers when debugging can be annoying. For example, you’ll see0.1e2
vs10
in ajets console
. Hence, the value is typecasted to a Ruby Integer. Integer typecasting can also be performed for comparison operations likePost.where("ttl.lt": Time.now)
for it to work correctly. - string: Dynomite typecasts
type: :string
with a.to_s
. This forces the value to be a String. - time: Since DynamoDB has no native time type, Dynomite stores a Time object as an ISO 8601 date string, IE:
2023-08-20T21:58:12Z
per AWS Docs. Dynomite typecasts DateTime to a Time so everything handled as Time internally.
Typecasting Default
The default type casting behavior is to infer based on the value itself. You can change this with:
config/initializers/dynomite.rb
Dynomite.configure do |config|
config.default_field_type = :infer # :string
end
Attribute Definitions
DynamoDB tables do have some “schema” information. This is in attribute_definitions
. I believe DynamoDB uses this for optimizations because when you define a index for a field, the attribute definitions must also be provided and a type must be specified. AWS DynamoDB then enforces the type on the field. Because of this, Dynamodb does a final typecast on the value to match what the attribute definition type is, Number, String, Boolean before persisting the data. Otherwise, the value will not be allowed to be saved.