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
Active Record + PostgreSQL: native support for timestamp with time zone
#41084
Conversation
ccf651b
to
4d0a141
Compare
timestamp with time zone
d223fe9
to
a5880ec
Compare
48295ec
to
b25f51c
Compare
c3aba26
to
8ac0517
Compare
Tests Active Record using Postgres with `timestamp` (not `timestamptz`) as the default datetime column type. rails/rails#41084 adds the relevant task, so that needs to be merged first.
e0e3421
to
d576a59
Compare
@rafaelfranca tagging you in since you commented here #21126 (comment) (but let me know if I should tag someone else - you get tagged in for everything). How's this looking so far? I'm not confident about the CI bit rails/buildkite-config#11 and don't really know how to test that it will work. I have been running |
@ghiculescu I am trying to upgrade Rails 6.x to Rails 7.x. I have a project that connects to multiple databases. In these databases some time fields are of type # Rails6.1.4.2
Post.last.published_at.class
# ==> ActiveSupport:: TimeWithZone
Post.last.published_at.to_s
# ==> 2022-02-23 10:33:36 everything is fine # Rails 7.0.1
Post.last.published_at.class
# ==> Time
Post.last.published_at.to_s
# ==> 2022-02-23 02:33:36 UTC To summarize: Rails 6.x formats timestamp as |
@Dearest that executable test needs I have a feeling I know what the issue is. Could you please get me the values of ActiveRecord::Base.time_zone_aware_attributes
ActiveRecord::Base.time_zone_aware_types
ActiveRecord::Base.skip_time_zone_conversion_for_attributes In both your Rails 6 and 7 versions. I have a feeling ActiveRecord::Base.time_zone_aware_types += [:timestamptz] |
@ghiculescu COOL! , I use this fix the issue ActiveRecord::Base.time_zone_aware_types += [:timestamptz] Before add Loading development environment (Rails 7.0.1)
[1] pry(main)> ActiveRecord::Base.time_zone_aware_attributes
=> true
[2] pry(main)> ActiveRecord::Base.time_zone_aware_types
=> [:datetime, :time]
[3] pry(main)> ActiveRecord::Base.skip_time_zone_conversion_for_attributes
=> [] Loading development environment (Rails 6.1.4.1)
[1] pry(main)> ActiveRecord::Base.time_zone_aware_attributes
=> true
[2] pry(main)> ActiveRecord::Base.time_zone_aware_types
=> [:datetime, :time]
[3] pry(main)> ActiveRecord::Base.skip_time_zone_conversion_for_attributes
=> [] |
@ghiculescu But I got another issue Loading development environment (Rails 6.1.4.1)
[1] pry(main)> User.last.created_at.to_s
=> "2021-12-08 18:13:34" But Rails7. I will get string include time zone Loading development environment (Rails 7.0.1)
[1] pry(main)> User.last.created_at.to_s
=> "2021-12-08 18:13:34 +0800" Can I configure the behavior of |
rails#41395 added support for the `timestamptz` type on the Postgres adapter. As we found [here](rails#41084 (comment)) this causes issues because in some scenarios the new type is not considered a time zone aware attribute, meaning values of this type in the DB are presented as a `Time`, not an `ActiveSupport::TimeWithZone`. This PR fixes that by ensuring that `timestamptz` is always a time zone aware type, for Postgres users.
rails#41395 added support for the `timestamptz` type on the Postgres adapter. As we found [here](rails#41084 (comment)) this causes issues because in some scenarios the new type is not considered a time zone aware attribute, meaning values of this type in the DB are presented as a `Time`, not an `ActiveSupport::TimeWithZone`. This PR fixes that by ensuring that `timestamptz` is always a time zone aware type, for Postgres users.
rails/rails#41084 introduces support for timestamp with time zone Currently, all our timestamp and datetime fields are without time zone (the previous default of datetime) This has resulted in some inconsistencies when trying to query for a time object not explicitly passed as UTC
rails/rails#41084 introduces support for timestamp with time zone Currently, all our timestamp and datetime fields are without time zone (the previous default of datetime) This has resulted in some inconsistencies when trying to query for a time object not explicitly passed as UTC
rails/rails#41084 introduces support for timestamp with time zone Currently, all our timestamp and datetime fields are without time zone (the previous default of datetime) This has resulted in some inconsistencies when trying to query for a time object not explicitly passed as UTC
In #21126 it was suggested to make "timestamp with time zone" the default type for datetime columns in PostgreSQL. This is in line with PostgreSQL best practices. This PR lays some groundwork for that.
This PR adds a configuration option,
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type
. The default is:timestamp
which preserves current Rails behavior of using "timestamp without time zone" when you dot.datetime
in a migration. If you change it to:timestamptz
, you'll get "timestamp with time zone" columns instead.If you change this setting in an existing app, you should immediately call
bin/rails db:migrate
to ensure yourschema.rb
file remains correct. If you do so, then existing columns will not be impacted, so for example if you have an app with a mixture of both types of columns, and you change the config, schema dumps will continue to output the correct types.This PR also adds two new types that can be used in migrations:
t.timestamp
andt.timestamptz
.Notes
datetime
format. The default is still "timestamp without time zone". A future PR could do that, but there was enough code here just getting the config option right.timestamp with time zone
columns correctly inschema.rb
#41395 which set some groundwork (and added some tests) for this.