git branch with migrations run - ruby-on-rails

I checked out a branch in git to experiment with developing a feature that involved making three migrations, which I have run. Preserving the very small amount of data in the db is not important. How do I handle this when merging the branch back into master? Should I rollback the migrations before merging, and then run them again after merged (as seemed to be suggested by one SO answer), or do I leave it as is and just commit everything to the branch and then merge it without rolling anything back. Another SO answer suggested removing the db from the gitignore file, but it wasn't clear if that was only necessary in situations where preserving data might be important.
# Ignore the default SQLite database.
/db/*.sqlite3

You should not track your *.sqlite3 development files in git.
You should
Merge master into your branch
Make sure all is well
Checkout master
Merge the branch back into master
Continue development
The merge will pull in your migrations from the branch. You could rollback before the merge, do the merge, and then migrate, but there's no need; the resulting schema at the end will be identical.
In situations where a rollback/migration would be necessary, it's likely your migrations between master and the branch conflict with one another somehow. This is something you'd fix in step #2 above when you're "Making sure all is well".
As a general rule, you should be able to take a completely blank database, run rake db:migrate and end up with an up-to-date database structure without anything failing. This is why step #2 above is important, to ensure you're not merging a breaking/conflicting migration back into master.
As for situations where you are risking losing data in development, this is what fixtures are for. You can use Rails seeding functionality, or a gem like factory_girl.

Related

How do I manage the database/migration when checking out earlier commits

Scenario description:
I have a master and a feature branch for my source control.
---- master
\-- feature
I have a column called useless_column for my User model, which is present in master branch, which i want to drop in feature branch.
Now, I drop useless_column using rails migrations in feature branch removing all code that depends on that column and commit. schema.rb and psql database are now updated.
Question:
Next, suddenly, I realize I made a mistake, and I want to go back to the master branch and discontinue working on feature branch. So, I git checkout -b master, but at this point I cannot db:rollback or schema:load or anything because the database has forgotten all the values in the useless_column which the master branch still depends on.
Does this mean I had to make a dump before I removed this column? If so, then the workflow is to make a database dump everytime you do a migration? If not, then how do you solve this problem?
Related link: How to work with Git branches and Rails migrations
Useful link: http://technotes.iangreenleaf.com/posts/2013-09-10-rails-migrations-and-schema.html

schema.rb messed up due to migrations in other branches

Currently I'm working with a huge rails application and multiple branches with each a new feature for this application.
It happens a lot a feature will require migrations, which shouldn't be a problem until you merge it with master: schema.rb got updated with the information of your dev database!
To clarify:
1. Branch A has migration create_table_x
2. Branch B has migration create_table_y
3. Branch A adds another create_table_z and runs db:migrate
4. You want to merge Branch A with Master and you see table_x, table_y and table_z in the schema.rb of Branch A.
It's not an option to reset+seed the database before every migration in a branch or create a database per branch. Due to the huge size of 2 GB SQL data, it would not be workable.
My question:
Is it really required to keep schema.rb in the repository since it gets rebuilt every migration?
If so, is it possible to build schema off the migrations instead of database dump?
you should keep the schema within your repo. running the migration will fix merge conflicts within your schema.rb file for you.
my simple take on your questions
Is it Required? not really, but good practice.
"It's strongly recommended to check this file into your version
control system." -schema.rb
It is possible? yes but you may want to ask yourself if you really save any time by doing so, either manually or building the schema off your migrations elsewhere and pushing it in.
you ge tthe added benefit of using
rake db:schema:load
and
rake db:schema:dump
http://tbaggery.com/2010/10/24/reduce-your-rails-schema-conflicts.html
Keeping schema.rb in the repo is important, because you want a new developer (or your test environment) to be able to generate a new database just from schema.rb. When you have a lot of migrations, they may not all continue to run, especially if they rely on model classes that don't exist, or have changed, or have different validations in effect than when the migration was first run. When you run your tests, you want to dump and recreate your database from schema.rb, not by re-running all the migrations every time you run the full test suite.
If you're working on two different feature branches simultaneously, and changing the database structure in both, I think schema.rb is the least of your problems. If you rename or remove a column in branch B, branch A is going to break whenever it references the old column. If all they're doing is creating new tables, it's not as bad, but then you want schema.rb to be updated when you merge from master into A, so that A doesn't try to run the migration a second time and fail because the new table already exists.
If that doesn't answer your question, maybe you could explain your workflow a little more?
Fresh Temporary DB as a quick workaround
For example, do the following whenever you need pretty db/schema.rb on particular branch:
git checkout -- db/schema.rb
switch to the different development database, i.e. update config/database.yml
rake db:drop && rake db:setup
rake db:migrate
commit your pretty db/schema.rb
revert changes in config/database.yaml

Is it considered safe to manually edit schema.rb in rails

I came across a problem where I was working on two branches on a rails project and each project has a migration to add a column. At the time, rake db:migrate:reset cause a problem and I solely relied on my schema.rb to correctly represent the state of my database. At one point, I came across a problem where a column added by branch A got into the schema of branch B. Since migrate:reset was not an option, I resorted to manually editing the schema file to. I committed this change that basically deleted the column from branch A that I did not need in branch B's schema.rb.
Problem came after I have merged branch A into master. When I tried to rebase branch B to master, I still had that commit in B to delete the column (which now has become relevant because it is in master) in the schema file. Git did not see a conflict for this and auto-merged it. At the end of my rebase, I found that my schema is inconsistent with what I have in master.
My fix is to edit the schema file again and manually add the previously deleted column back to the schema file. My question is: Is this considered unconventional? dangerous? hacky?
Right now it involves one column but if this involved multiple column deletions/additions the (dangerous?) solution could lead to more problems and db/schema.rb inconsistency.
It is generally considered a bad practice to edit your schema.rb file.
According to the Rails Guide on Migrations:
Migrations, mighty as they may be, 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.
schema.rb gets updated every time you run a new migration:
Note that running the db:migrate also invokes the db:schema:dump task, which will update your db/schema.rb file to match the structure of your database.
I'd recommend just spending some time to sort things out and get the schema.rb file back on track and correct up to the latest set of migrations.

rake db migration issues

Some questions on db migration tasks (rake db:migrate)
Does it make sense to rename the file names, if there is a spelling mistake.
(e.g. CreaetFoos.rb to CreateFoos.rb)
I created a migration script (say version '3') by mistake during the dev process and I would like it to be removed from git. What if I had already migrated to be at the current level of '6', should I just rollback till '2', remove migration script corresponding to '3' from git and re-run migration scripts. Will schema_migrations hold the right data in this case?
I would like to create a migration script during the dev process, but I don't want this to be considered as part of the migration script unless I call it complete (i.e. I don't want other developers to use a incomplete migration script which is checked into git). How do I handle this?
A multi-part question! Let me answer them in the proper parts.
[Question 1] Does it make sense to rename the file names, if there is a spelling mistake.
If it bothers you that much, yes. It would also bother me too.
[Question 2] [Wall of text about removing a migration]
Once a migration has been committed to your version control system, it should remain untouched. If it's modified, then you and other developers would need to roll it back and forward in order to get its changes again. It would be much better if you were to never touch old migrations and to fix any issues in new migrations. There are exceptions to this rule, which will be obvious when you encounter them.
Such as migrations that drop entire tables by accident.
[Question 3] Handling of migrations committed to version control
It's best practice to work in your own branch if you're going to be committing work that is incomplete. By doing this, you will leave the main branch ("master", probably) pristine and complete, allowing for other developers to continue on their own work.
Once you've got that migration sorted, then you will merge that branch back into master.

Managing Rails Migrations for different branches on the same machine

I'm a one-man-band at the company I work for. I develop a Rails application for internal use within the company. Since the beginning of the project I have used SVN for source control and done most, but not all, development in trunk. Occasionally, when I have had very significant changes to make, I have branched and made the changes merging back in when done. All very typical.
However, none of those "significant changes" that I have had to make have ever touched the database migrations. They have always been view/controller stuff.
In this situation, with one development box, how do I play around with migrations and various database changes that I may or may not keep? I don't want to have to remember to revert all the migrations back to the beginning of the branch before I throw the branch out if it doesn't work.
I have considered setting up special development environments and databases (app_branch instead of app_development) but that seems to work strongly against the notion of "easy branching" that experimental development tends to rely on.
Are there best practices for this situation? What are others out there doing in this situation?
I try hard to keep my development database "droppable." If I lose it all - no big deal. My migrations are ready to build it up again from scratch and there's always a script with seed / test data in it somewhere. I guess it's not especially clever.
If I needed a new branch for database work, I would just check it out, drop, create, rake, and then seed. I guess I'd write a script to get it done because when I go to adandon the branch, I'm going to have to go through the same process again from the trunk.
Make sure your schema.rb file is in version control. That way, as you switch branches, you can drop your DB and then do rake db:schema:load as necessary.
Also, you really should switch to Git. It will make branch management a lot easier than SVN. (I speak from lots of experience with both programs.)
Well, if you want to have different schemas, you'll need multiple databases. "Easy branching" refers to source control, typically, and not databases. As far as I know there's no easy way to branch databases like you would branch in, say, git.
One thing we do to manage our dev/production branches is we check our current git branch in our database.yml file. If the current branch is production, we use one database, otherwise we use our dev database. something along the lines of this:
<% if 'git branch' =~ /^\* production/
db = 'production_database'
else
db = 'development_database
end %>
development:
database: <% db %>
Note, the 'production_database' refers to a local version of the production schema, not the live production database.
I wrote a script for dealing with this exact problem. It is based around git, but you could easily change it to work for svn:
https://gist.github.com/4076864
Given a branch name it will:
Roll back any migrations on your current branch which do not exist on the given branch
Discard any changes to the db/schema.rb file
Check out the given branch
Run any new migrations existing in the given branch
Update your test database
I find myself manually doing this all the time on our project, so I thought it'd be nice to automate the process.
If I am creating a branch where you are making siginificant changes, you can create a copy of the database before creating your migrations then change the development section of database.yml inside the branch. Leave your :production section alone and then decide which version of the database you want to keep for future development when you merge the branch back into the trunk.
We do this with feature releases. I'll have local DBs for version 1, 2, 3 like "db_v1", db_v2", etc. As we roll through the versions, each subsequent development branch gets an edit in database.yml while the trunk stays on the last version for bug fixing.

Resources