I have a table: db/migrate/20140731201801_create_voc_brands.rb:
class CreateVocBrands < ActiveRecord::Migration def change create_table :voc_brands do |t| t.string :name t.timestamps end end end
But I need to change table to this(if I would create it from zero):
class CreateVocBrands < ActiveRecord::Migration def change create_table :voc_brands, :id => false do |t| t.uuid :id, :primary_key => true t.string :name t.timestamps end add_index :voc_brands, :id end end
How can I change this using migration?
I had the same problem as yours. To migrate from default id to use uuid, I think you could something similar to what I had:
class ChangeVocBrandsPrimaryKey < ActiveRecord::Migration def change add_column :voc_brands, :uuid, :uuid, default: "uuid_generate_v4()", null: false change_table :voc_brands do |t| t.remove :id t.rename :uuid, :id end execute "ALTER TABLE voc_brands ADD PRIMARY KEY (id);" end end
I know migrations are preferred way to made any db change but below approach is awesome. It is possible to use direct queries to PostgreSQL to convert table with existing data.
For primary key:
ALTER TABLE students ALTER COLUMN id DROP DEFAULT, ALTER COLUMN id SET DATA TYPE UUID USING (uuid(lpad(replace(text(id),'-',''), 32, '0'))), ALTER COLUMN id SET DEFAULT uuid_generate_v4()
For other references:
ALTER TABLE students ALTER COLUMN city_id SET DATA TYPE UUID USING (uuid(lpad(replace(text(city_id),'-',''), 32, '0')))
The above left pads the integer value with zeros and converts to a UUID. This approach does not require id mapping and if needed old id could be retrieved.
As there is no data copying, this approach works quite fast.
To handle these and more complicated case of polymorphic associations please use https://github.com/kreatio-sw/webdack-uuid_migration. This gem adds additional helpers to ActiveRecord::Migration to ease these migrations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With