getting-started-with-migrations
What is a migration?
It's when you want to run a transaction in the database. A migration will get run as a single transaction unless you specify disable_ddl_transaction! in the migration
Applicable for:
- Adding/Removing Tables
- Adding/Removing Properties(Columns, Defaults, Constraints)
- Adding/Removing Indexes
- Adding/Removing Functions
You can use migrations to alter data as well, but not recommended.
How to get started:
If you want to add a new table:
rails g model [TableName]
Otherwise:
rails g migration [descriptionOfWhatYouWantToDo] <-- e.g. addAppIndexToAppAccesses
When you generate a migration, you'll have a file like:
db/migrate/20191232224001_this_is_an_example.rb
class ThisIsAnExample < ActiveRecord::Migration[5.2]
def change
end
end
What is change?
Change is actually two components rolled up into one. Change handles both up and down methods, where up is running a migration or transaction, and down is rolling back or undoing a migration.
Guide on ActiveRecord Migrations:
https://guides.rubyonrails.org/active_record_migrations.html
Running the migration
bundle exec rake db:migrate <--will run any migration not yet run
bundle exec rake db:migrate:up VERSION=20191232224001 <-- will run migration for specific version
Rolling back the migration
bundle exec rake db:rollback <-- will rollback the most recent migration run
bundle exec rake db:migrate:down VERSION=20191232224001 <-- will rollback migration for specific version
Running SQL migrations (Views, Materialized Views, Functions)
SEE 20190517180237_add_plpgsql_functions_and_views.rb for example You'll want to separate change into the separate up/down functions since rollback doesn't work well for SQL migrations
def up
execute <<-SQL
CREATE OR REPLACE FUNCTION sanitize_unicode(_text TEXT) RETURNS TEXT AS $$
SELECT REGEXP_REPLACE(_text, '\\(?<!\\\\)(?:\\\\)*(?!\\)u0000', '\\\\u0000','g');
$$ LANGUAGE SQL;
SQL
### Or you can read the function from a file
# sql = File.read("lib/database/sanitize_unicode_function.txt")
# execute sql
end
def down
execute <<-SQL
DROP FUNCTION IF EXISTS sanitize_unicode(TEXT);
SQL
end
- Execute will run the function/query.
- You can have the query directly in the migration file or as a separate file
- When you run migrations in general, you should check for the existence of what you're creating/removing. The reason is because sometimes a migration may get run multiple times on an environment (for example because there is a version collision, so one version number gets updated).