-
-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to store datetimes as ISO-8601 formatted strings #223
Add option to store datetimes as ISO-8601 formatted strings #223
Conversation
README.md
Outdated
@@ -598,6 +598,7 @@ Listed below are all configuration options. | |||
* `sync_retry_max_times` - when Dynamoid creates or deletes table synchronously it checks for completion specified times. Default is 60 (times). It's a bit over 2 minutes by default | |||
* `sync_retry_wait_seconds` - time to wait between retries. Default is 2 (seconds) | |||
* `convert_big_decimal` - if `true` then Dynamoid converts numbers stored in `Hash` in `raw` field to float. Default is `false` | |||
* `convert_date_to_string` - if `true`, datetimes will be stores as ISO-8601 formatted strings. When `false`, datetimes will be stores as UNIX timestamps with milisecond precission. Defaule is `false` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, default
lib/dynamoid/persistence.rb
Outdated
@@ -208,7 +197,7 @@ def dynamo_type(type) | |||
:string | |||
else | |||
raise 'unknown type' | |||
end | |||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just my editor formatting the code. I'll update.
1 similar comment
lib/dynamoid/persistence.rb
Outdated
when :utc | ||
time_for_timezone(value, 'UTC') | ||
when :local | ||
time_for_timezone(value, Time.now.getlocal.zone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ActiveSupport::TimeZone
works badly with decree time and may loose 1 hour. That's why we used Time.at(value).to_datetime
to convert time.
lib/dynamoid/persistence.rb
Outdated
ActiveSupport::TimeZone[Dynamoid::Config.application_timezone].at(value).to_datetime | ||
end | ||
end | ||
parse_datetime(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good refactoring. The feature could be done just with one additional line
value = DateTime.iso8601(value).to_time.to_i if Dynamoid::Config.convert_date_to_string
lib/dynamoid/config.rb
Outdated
@@ -26,6 +26,7 @@ module Config | |||
option :sync_retry_max_times, default: 60 # a bit over 2 minutes | |||
option :sync_retry_wait_seconds, default: 2 | |||
option :convert_big_decimal, default: false | |||
option :convert_date_to_string, default: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To support existed projects and data we may need to specify this format not globally but for specific model and field (as well as allow to set it globally)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrykonchin wouldn't the default value of false
make it backwards compatible with any existing implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pboling It would, sure.
But you could want to keep old format for existing tables and new format for new ones. You couldn't use new format if already have data in old one in any table.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. Agreed, this has to be model-specific per field.
spec/dynamoid/persistence_spec.rb
Outdated
end | ||
end | ||
|
||
include_examples 'dump_datetime_attributes' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would wrap it with context context 'when convert_date_to_string == false' do
spec/dynamoid/persistence_spec.rb
Outdated
user = User.create(last_logged_in_at: time) | ||
user = User.find(user.id) | ||
expect(user.dump[:last_logged_in_at]).to be_a(String) | ||
expect(user.dump[:last_logged_in_at]).to eq '2017-06-20T05:00:00+00:00' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test passes only because it runs in UTC timezone and it fails when local time zone isn't UTC.
You should set application_timezone='UTC'
for this test case. It's local
by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we would have tests for multiple time zones for any feature based on parsing time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pboling Agree, but I didn't find a way to change timezone in tests. We can travel in time with Timecop
but we cannot change timezone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New option option :convert_date_to_string, default: false
must be model specific per field, not global.
d1d558d
to
7963591
Compare
7963591
to
a85fc93
Compare
README.md
Outdated
class Document | ||
include DynamoId::Document | ||
|
||
field :sent_at, :datetime, convert_date_to_string: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have similar option for boolean field store_as_native_boolean
field :active, :boolean, store_as_native_boolean: true
It makes sense to name new option in similar way
@pboling What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, it may be useful to apply this new option globally and override it for specific field
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should follow existing naming patterns. 👍
2 similar comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now addresses everything except @andrykonchin 's suggestion to make the setting an optional global setting with a per model override.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other improvements like global option or support string format for date
fields can be done in separate PRs
Currently datetimes are stored in DynamoDB as
:number
(UNIX timestamps)This pr add the option to store these timestamps as
:string
(ISO 8601)Reference: