Rails has a rake db:schema:load command. When it can be useful, in what cases to apply it?

    2 answers 2

    The command is useful if you need at one stroke to set the structure in the database the same as in schema.rb or schema.sql your project.

    Typically, the database structure is modified through migrations and rake db:migrate . This method is good for three reasons:

    1. Incremental change of the database - only those migrations that have not yet been rolled onto the current database roll;

    2. There is no threat of losing existing data - no changes are made to already existing tables and data, unless this is clearly indicated in new migrations;

    3. The ability to roll back to n migrations backwards - using rake db:rollback .

    This also updates the schema.rb file. After successive knurling of all migrations, in this file there will be a structure reflecting all changes through migrations, from the very first to the most recent one. And, in an amicable way, this file needs to be committed to git along with other project files.


    Now imagine the situation:

    • The project instituted several branches, for several different features;
    • In each branch, one way or another, it turned out to be necessary to modify the structure of the database;
    • This means that each branch has its own migrations;
    • We are in branch A, created migrations in it, rolled them - changed the structure of the database;
    • Suddenly, we needed to go to branch B and do something there;
    • We jump to it using git checkout Б ;
    • Now in the editor, we see the code for branch B, and we can work with it;
    • But the data structure created by migrations from branch A. remained in the database.

    Here is a conflict. Ideally, we need to remove from the database all the tables, fields and indices created by migrations from branch A, go to branch B, and roll all the migrations from branch B. Something like this:

    • rake db:rollback - n-times to roll back n-migrations;
    • git checkout Б ;
    • rake db:migrate .

    And when we do everything in branch B and want to return to branch A, we need to do this sequence of operations again. Roll back all migrations of branch B, go to branch A, and roll all migrations of branch A.

    rake db:schema:load helps get rid of this. The fact is that in each branch, when we created migrations, we rolled them and made a commit — we also schema.rb file schema.rb . So, if we move from branch A to branch B, we will see that the structure in schema.rb corresponds exactly to the migrations that should be applied to branch B. And we can simply load this structure into the database. As a result, the algorithm for switching from branch to branch is simplified to:

    • git checkout Любая-ветка
    • rake db:schema:load

    But the nuance remains. Since db:schema:load , in essence, rolls the finished structure onto the database from scratch — all existing tables, and, importantly for us, the data in the tables are deleted. That is, at the output we get, even if the database with the current structure, but without data. And we need to think over the data rolling separately. One option is to keep rolling data in seeds.rb and, after switching to another branch and using rake db:schema:load , also use rake db:seed .

      It can be useful if you need to recreate the database structure in a different environment / database, without using migration (for example, for the reason that they take too long to complete). For example, for a test environment, you can execute the command

       rake db:test:load 

      and the current schema from db / schema.rb will be deployed in the test database, without successive migrations. This becomes especially important in the case when you work in containers and test runs you start every time with a clean database, and you do not want to collapse the old migrations (replacing them with the contents of schema.rb) (for example, comments are stored there for reasons of choosing the index).