Don't delete columns, deprecate them
There is a point in time where you just stop needing a column in the database. The most logical approach is to delete it, but it turns out this isn’t the smartest thing to do.
Story time
One of my first tasks from work was to integrate Revolut in our platform. Payment processing as a first task for an intern is brave, but that’s another story.
At one point, it was best to move the payment details fields into a separate table. This way we could stay more organized and add other payment methods in the future.
I moved the iban
field from the User
model to the PaymentDetails
model. “Moved” is a relative term, because what we actually do is create a new table, add the columns there, and delete the columns from the old one. So i did just that.
I changed how we use iban
everywhere in the code(user.iban -> user.payment_details.iban
), added rake tasks that moved our data to the new table, and even wrote some tests. Even after all of this there is always a possibility that stuff breaks.
What i didn’t think about was that by deleting the column we lose our ability to rollback if something bad happens. Backing up our database is a good measure, but why risk it?
Thats why we deprecate the column. Here is how a Rails migration will look like:
1
2
3
4
5
class DeprecateIbanFromUser < ActiveRecord::Migration[7.1]
def change
rename_column :user, :iban, :deprecated_iban
end
end
Summary
Don’t delete columns. Rename them to deprecated_
and check to see if something breakes. Nothing should, but if it brakes you can just rename the column back, but you can’t undelete the column.
After a month we can delete it entirely, when we are sure nothing broke in production.