Fix milestones migration not updating ID sequence

When we insert a record in PostgreSQL and we specify the ID, the
internal ID sequence for that table isn't updated.

In order to keep the original IDs so we didn't break any foreign keys,
we specified the IDs when copying the table, resulting in a table having
its ID sequence with a value of an existing record. When trying to
insert a new record, we got a `PG::UniqueViolation` exception.

Updating the sequence after the data migration might not be the most
elegant solution, but it's easy to do and it's already been tested on a
production environment.
This commit is contained in:
Javi Martín
2018-11-19 18:42:38 +01:00
parent 87b073cbca
commit d3882df437
2 changed files with 9 additions and 0 deletions

View File

@@ -91,6 +91,10 @@ namespace :milestones do
"budget_investment_statuses" => "milestone_statuses", "budget_investment_statuses" => "milestone_statuses",
"budget_investment_milestone_translations" => "milestone_translations" "budget_investment_milestone_translations" => "milestone_translations"
}.each do |original_table, migrated_table| }.each do |original_table, migrated_table|
ActiveRecord::Base.connection.execute(
"select setval('#{migrated_table}_id_seq', (select max(id) from #{migrated_table}));"
)
unless count_rows(original_table) == count_rows(migrated_table) unless count_rows(original_table) == count_rows(migrated_table)
raise "Number of rows of old and new tables do not match! Rolling back transaction..." raise "Number of rows of old and new tables do not match! Rolling back transaction..."
end end

View File

@@ -66,6 +66,11 @@ describe "Milestones tasks" do
expect(milestone.updated_at.to_date).to eq Date.today expect(milestone.updated_at.to_date).to eq Date.today
end end
it "Updates the primary key sequence correctly" do
run_rake_task
expect { create(:milestone) }.not_to raise_exception
end
context "Milestone has images and documents" do context "Milestone has images and documents" do
let(:milestone_id) do let(:milestone_id) do
ActiveRecord::Base.connection.execute( ActiveRecord::Base.connection.execute(