Skip to content
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

Ridgepole always changes datetime columns after updating ActiveRecord to v7.0 #381

Closed
sankichi92 opened this issue Feb 12, 2022 · 5 comments

Comments

@sankichi92
Copy link
Contributor

sankichi92 commented Feb 12, 2022

I'm sorry. Another problem on datetime columns of ActiveRecord v7.0 remains even after #380.
After updating ActiveRecord from v6.1 to v7.0, the ridgepole -a command changes datetime columns every time.

Steps to reproduce

First, with ActiveRecord v6.1:

# Gemfilie
source "https://rubygems.org"

gem "activerecord", "6.1.4.6"
gem "pg", "1.3.1"
gem "ridgepole", "1.0.3"
# Schemafile
create_table :articles do |t|
  t.string :title
  t.text :content
  t.datetime :published_at
  t.timestamps
end
$ bundle install
$ bundle exec ridgepole -c '{"adapter":"postgresql","database":"blog"}' -a
Apply `Schemafile`
-- create_table("articles")
   -> 0.0088s
$ bundle exec ridgepole -c '{"adapter":"postgresql","database":"blog"}' -a
Apply `Schemafile`
No change

It's OK, but after updating ActiveRecord to v7.0,

diff --git a/Gemfile b/Gemfile
--- a/Gemfile
+++ b/Gemfile
@@ -1,5 +1,5 @@
 source "https://rubygems.org"
 
-gem "activerecord", "6.1.4.6"
+gem "activerecord", "7.0.2.2"
 gem "pg", "1.3.1"
 gem "ridgepole", "1.0.3"
$ bundle update
$ bundle exec ridgepole -c '{"adapter":"postgresql","database":"blog"}' -a
Apply `Schemafile`
-- change_column("articles", "published_at", :datetime, {:null=>true, :default=>nil})
   -> 0.0037s
-- change_column("articles", "created_at", :datetime, {:null=>false, :default=>nil})
   -> 0.0006s
-- change_column("articles", "updated_at", :datetime, {:null=>false, :default=>nil})
   -> 0.0007s
$ bundle exec ridgepole -c '{"adapter":"postgresql","database":"blog"}' -a
Apply `Schemafile`
-- change_column("articles", "published_at", :datetime, {:null=>true, :default=>nil})
   -> 0.0037s
-- change_column("articles", "created_at", :datetime, {:null=>false, :default=>nil})
   -> 0.0006s
-- change_column("articles", "updated_at", :datetime, {:null=>false, :default=>nil})
   -> 0.0007s

change_column for datetime columns runs on every ridgepole -a command.

System configuration

  • PostgreSQL version: 14.1
  • Ruby version: 3.1.0
@winebarrel
Copy link
Collaborator

Can you post the results of pg_dump?

@sankichi92
Copy link
Contributor Author

sankichi92 commented Feb 12, 2022

Here is the result of pg_dump:

pg_dump blog
--
-- PostgreSQL database dump
--

-- Dumped from database version 14.1
-- Dumped by pg_dump version 14.1

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: articles; Type: TABLE; Schema: public; Owner: takahiro-miyoshi
--

CREATE TABLE public.articles (
    id bigint NOT NULL,
    title character varying,
    published_at timestamp without time zone,
    created_at timestamp without time zone NOT NULL,
    updated_at timestamp without time zone NOT NULL
);


ALTER TABLE public.articles OWNER TO "takahiro-miyoshi";

--
-- Name: articles_id_seq; Type: SEQUENCE; Schema: public; Owner: takahiro-miyoshi
--

CREATE SEQUENCE public.articles_id_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


ALTER TABLE public.articles_id_seq OWNER TO "takahiro-miyoshi";

--
-- Name: articles_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: takahiro-miyoshi
--

ALTER SEQUENCE public.articles_id_seq OWNED BY public.articles.id;


--
-- Name: articles id; Type: DEFAULT; Schema: public; Owner: takahiro-miyoshi
--

ALTER TABLE ONLY public.articles ALTER COLUMN id SET DEFAULT nextval('public.articles_id_seq'::regclass);


--
-- Data for Name: articles; Type: TABLE DATA; Schema: public; Owner: takahiro-miyoshi
--

COPY public.articles (id, title, published_at, created_at, updated_at) FROM stdin;
\.


--
-- Name: articles_id_seq; Type: SEQUENCE SET; Schema: public; Owner: takahiro-miyoshi
--

SELECT pg_catalog.setval('public.articles_id_seq', 1, false);


--
-- Name: articles articles_pkey; Type: CONSTRAINT; Schema: public; Owner: takahiro-miyoshi
--

ALTER TABLE ONLY public.articles
    ADD CONSTRAINT articles_pkey PRIMARY KEY (id);


--
-- PostgreSQL database dump complete
--

@sankichi92
Copy link
Contributor Author

sankichi92 commented Feb 12, 2022

I found adding precision: nil to datetime columns avoids this problem.

diff a/Schemafile b/Schemafile
--- a/Schemafile
+++ b/Schemafile
@@ -1,5 +1,5 @@
 create_table :articles do |t|
   t.string :title
-  t.datetime :published_at
-  t.timestamps
+  t.datetime :published_at, precision: nil
+  t.timestamps precision: nil
 end
$ bundle exec ridgepole -c '{"adapter":"postgresql","database":"blog"}' -a
Apply `Schemafile`
No change

Since the default precision of datetime columns is changed from nil to 6 according to ActiveRecord v7.0 CHANGELOG:

  • Set precision 6 by default for datetime columns.

    By default, datetime columns will have microseconds precision instead of seconds precision.

ActiveRecord schema dump avoids this problem by adding the version to schema dump.

  • Dump the database schema containing the current Rails version.

    Since Set precision 6 by default for datetime columns rails/rails#42297, Rails now generate datetime columns
    with a default precision of 6. This means that users upgrading to Rails 7.0 from 6.1,
    when loading the database schema, would get the new precision value, which would not match
    the production schema.

    To avoid this the schema dumper will generate the new format which will include the Rails
    version and will look like this:

    ActiveRecord::Schema[7.0].define
    

    When upgrading from Rails 6.1 to Rails 7.0, you can run the rails app:update task that will
    set the current schema version to 6.1.

I think this is an incompatibility problem of ActiveRecord v7.0, not a Ridgepole problem.
So how about adding a Rails v7.0 upgrading guide (precision: nil for datetime columns) to README?
Or introducing a configuration method for Rails DSL versions like ActiveRecord scheme dump.

@winebarrel
Copy link
Collaborator

Also added note about datetime type to README. 6995092
Thank you.

@sankichi92
Copy link
Contributor Author

Thank you 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants