Is it permissible to delete (or archive) old migration files in a Rails app if the schema is stable?
My migrations are numerous and I suspect there may be some problem in there somewhere, because I occasionally have problems migrating the database on Heroku.
You don't need to keep around your old migration files in a Rails app, because your database schema should be captured either in schema.rb or an equivalent SQL file that can be used to regenerate your schema.
Migrations are not the authoritative source for your database schema. That role falls to either db/schema.rb or an SQL file which Active Record generates by examining the database. They are not designed to be edited, they just represent the current state of the database.
There is no need (and it is error prone) to deploy a new instance of an app by replaying the entire migration history. It is much simpler and faster to just load into the database a description of the current schema, which is in schema.rb or the SQL file.
This file should be versioned and kept in source control.
To set up automatic schema.rb generation, modify config/application.rb by the config.active_record.schema_format setting, which may be :ruby or :sql.
If :ruby is selected then the schema is stored in db/schema.rb.
If :sql is selected, the schema is dumped out in native SQL format of
your database.
You can delete your old migrations. After you have done this, when you are setting up your app you will need to run:
rake db:schema:load
Instead of:
rake db:migrate
here is what I did, I found the last version migrated on production ActiveRecord::SchemaMigration.last.version and deleted all the migrations before that in my source code.
not the best way but I did find db/migrate -type f, copied the list of files before the last version and pbpaste | rm (macos).
Related
I have a rails 5 app with PostgreSQL as database, and I for some reason have dropped the database and also deleted all the migration files in db/migrate folder. Is there any way to generate a single migration file based on models and views without generating individual migration files specifying the columns to rebuild the database?
If you have the db/schema.rb you can setup the database from there.
rails db:schema:load
Will setup the database from the schema.
It is also relatively simple to convert the schema.rb to an initial setup migration, effectively you copy everything that's inside ActiveRecord::Schema.define(version: timestamp) do block
Then paste it into a new migration inside a def up ... end method.
This is also the exact time to get your project into git version control and avoid nightmare situations like this again.
I have been developing a project in Ruby on Rails. During the development I have generated tons of migration files for my project. Sometimes I have added and deleted columns from different tables.
Is there a way that I could consolidate all the migrations from multiple files into a single file?
TL;DR
What you need isn't a consolidated set of migrations; it's a single schema file and an optional seeds.rb file. Rails generally maintains the schema automagically when you run migrations, so you already have most of what you should need with the possible exception of seed data as described below.
Use the Schema, Not Migrations
In general, you shouldn't be maintaining a large pool of migrations. Instead, you should periodically clear out your migrations, and use schema.rb or schema.sql to (re)create a database. The Rails guides specifically state:
There is no need (and it is error prone) to deploy a new instance of an app by replaying the entire migration history. It is much simpler and faster to just load into the database a description of the current schema...Because schema dumps are the authoritative source for your database schema, it is strongly recommended that you check them into source control.
You should therefore be using bin/rails db:schema:load rather than running migrations, or run the associated Rake task on older versions of Rails.
Data Migrations
While you can use migrations to fix or munge data related to a recent schema change, data migrations (if used at all) should be temporary artifacts. Data migrations are almost never idempotent, so you shouldn't be maintaining data migrations long-term. The guide says:
Some people use migrations to add data to the database...However, Rails has a 'seeds' feature that should be used for seeding a database with initial data. It's a really simple feature: just fill up db/seeds.rb with some Ruby code, and run rake db:seed...This is generally a much cleaner way to set up the database of a blank application.
Database seed data should be loaded with bin/rails db:seed (or the associated Rake task) rather than maintaining the data in migrations.
There is a gem that purports to do exactly what you describe in the question - check out Squasher.
From the README:
"Squasher compresses old migrations in a Rails application. ... Squasher removes all the migrations and creates a single migration with the final database state of the specified date (the new migration will look like a schema)."
You'll have to do the merge manually.
But if you want only a single file, there is db/schema.rb. It contains a snapshot of current database schema. You can load it directly in database if you want.
I have a project that has had alot of editing to the postgresql database.
I am tring to find out is there a way to build a new db:rake file so i can rebuild the database on new server easily. Without manually editing the db:rake files.
thanks
Ruby 1.9.3
CentOS 6.4
Ruby on Rails 3
postgresql 9.3
For clarity, I am assuming you are referring to the migration files when you mention db:rake files.
In Rails, you don't want to rebuild the database using migration files. They can quickly become outdated, referring to things that no longer exist, etc. Instead, it is best practice to recreate the database using your schema.rb file instead. This is touched on an answer I wrote a while back. In short, the schema.rb file represents your database table structure; a snapshot, if you will. Note that it does not contain data, only the table structure.
In your scenario, in order to create, or ensure your schema.rb is up to date, you simply need to dump the schema, like so:
rake db:schema:dump
This regenerates the schema.rb file. Then, to rebuild the database from this file in another environment, simply reload the schema, like so:
rake db:schema:load
As stated above, the schema.rb does not contain any data from the tables, it merely represents the structure. If you want to preload the database with initial / default values, you will want to use the seed.rb file. Simply write your .create statements, and run it like so:
rake db:seed
Should we include schema.rb while commiting to GIT? or should we ignore it? what is the right approach?
Well the standard schema.rb file for Rails 2 has this at the end of the comment block at the top of the file:
# It's strongly recommended to check this file into your version control system.
The Rails 3 schema.rb that I have kicking around says the same thing. I think the comment says it all.
Update in response to comments:
Yes, mistakes can be made and you can get conflicting changes and bugs mangling your schema.rb but that's why you want it under revision control, revision control allows you to keep track of everything and backup when needed. There is only one thing in your entire source tree that specifies your database schema and that is schema.rb. Your database schema absolutely is a critical artifact and anything that important needs to be tracked in revision control.
Any update/merge problems with schema.rb should be sorted out just by sorting out your conflicting migrations so schema.rb will get fixed as a side effect of fixing the real problem.
Yes, schema.rb is a generated file but it is only generated in the sense that your text editor generates your pancake.rb model file or an unedited scaffold file is generated.
Yes, you could rebuild your schema.rb file by building a new database and then running all of your migrations. But, you should clear out your old migrations now and then to avoid having to check hundreds of migration files every time you rake db:migrate so "rebuild and run all the migrations" often isn't an option in a highly active project.
Yes. The schema file is used to configure your database when using rake db:reset and other commands. Migrations should only be used when changing the database schema and will always result in a new schema file.
Well, it's not included on .gitignore by default. So, I think that you would not have a problem including it(I do in my projects, without any problem).
I don't commit this file to Git, because it create when I launch rake db:migrate.
If I will commit this file to Git, I cannot pull new changes from server after each db:migrate.
How can I go about generating an image of a database schema used in a Rails app?
Have you tried rake db:schema:dump?
Essentially, make sure that your database.yml file is referencing the database you wish to dump, and then run the command. It'll take all of the tables and indexes in said database and then write it out to schema.rb.
Note that you should rename schema.rb once it contains the dump; otherwise, it could it overwritten.