Active Record + PostgreSQL: native support for timestamp with time zone#41084
Active Record + PostgreSQL: native support for timestamp with time zone#41084pixeltrix merged 1 commit intorails:mainfrom
timestamp with time zone#41084Conversation
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:36everything is fine # Rails 7.0.1
Post.last.published_at.class
# ==> Time
Post.last.published_at.to_s
# ==> 2022-02-23 02:33:36 UTCTo 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_attributesIn 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 |
|
hi @ghiculescu sorry for mentiong why there is no documentation for this config? I think it should be mentioned here https://guides.rubyonrails.org/active_record_postgresql.html and where to put this config? in and also I got confused by this line in your post
I have run rails db:migrate but nothing changing at all, do you mean I should make a columntype changes manually? like |
I agree. Would you like to make a PR? The snippet from https://guides.rubyonrails.org/configuring.html#activerecord-connectionadapters-postgresqladapter-datetime-type should work anywhere in If there were no changes to |
|
@ghiculescu my mistake doing indeed changing something on schema.rb the changes are from this to this what I mean by not changing after doing is that intentional? |
|
Yes that’s intentional. It won’t rebuild your database, it just applies to new columns going forward. We need to reset the schema file to ensure you’re generating a test database correctly. |
|
Hi @ghiculescu and @laptopmutia, I created this Rails Guides Active Record PostgreSQL PR to document why and how to use this new configuration option. #53687 This was based on generating a new Rails 8, realizing this data type is not the default, then realizing I didn't know how to configure my app to use it. I found this PR, then saw the suggestion it's not document yet, and a suggestion to put it into the Rails Guides page. I picked the data types section. Let me know what you think! |
|
Hi @ghiculescu thanks for this PR. If I don't add ActiveSupport.on_load(:active_record_postgresqladapter) do
self.datetime_type = :timestamptz
# Had to add this
ActiveRecord::Base.time_zone_aware_types << :timestamp
endI was confused how when I set I think technically what you wrote is correct for fresh applications (from scratch) but for existing applications, I think it's worth mentionning that I don't know if I should create a documentation PR, or add |
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:timestampwhich preserves current Rails behavior of using "timestamp without time zone" when you dot.datetimein 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:migrateto ensure yourschema.rbfile 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.timestampandt.timestamptz.Notes
datetimeformat. 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 zonecolumns correctly inschema.rb#41395 which set some groundwork (and added some tests) for this.