add_column_with_default and Arel.sql literal did not backfill data
alan-pie opened this issue · 4 comments
I had the following migration which I expected to backfill sent_at
with the value from created_at
, but ended up just creating the new column with null values. Is there a bug or did I do something wrong?
online_migrations 0.5.4
postgresql 14.6
active_record 6.1.7.1
class AddSentAtToPayouts < ActiveRecord::Migration[6.1]
disable_ddl_transaction!
def change
add_column_with_default(
:payouts,
:sent_at,
:timestamp,
default: Arel.sql('created_at')
)
end
end
That is not possible in PostgreSQL - you should have literals (numbers, strings etc) as a DEFAULT
or function calls (like random()
, current_timestamp
etc).
If you want to have sent_at
be set as a default to created_at
, that should probably be done via db triggers or model callbacks.
If you want to just create a new column and populate existing rows with the value of created_at
, without setting a default of some kind, then add_column
+ update_column_in_batches(:payouts, :sent_at, Arel.sql('created_at'))
should work.
I see. This line led me to believe it was possible:
But now I see that for newer versions of PostgreSQL it doesn't use that branch.
Would this work if Arel.sql
literals were considered a volitile_default?
?
No, Postgres SQL syntax just does not allow to specify other columns as a DEFAULT
.
You can manually try (to see the error)
Seems like this gem is not able to overcome that PostgreSQL limitation.
Feel free to ask any questions, if you have one.