When working on a project, I keep track of all the changes I make to a database in a notepad file. Then, later, I manually write all the changes in rails' db migration file.
But it should be possible to compare the schema of a backup of my database, with the new version of my database, and automatically detect the differences. And generate the rails db migration file automatically.
Is there a tool that can compare two database schema's and automatically generate rails' db migration files?
As far as I'm aware, there's no tool that will do it automatically, however, you can get most of the way there just using rake db:schema:dump with source control.
Create a new Rails project and do the following:
Update database.yml to connect to your first database.
Use rake db:schema:dump to populate schema.rb and commit schema.rb to git.
Update database.yml to connect to your second database and again run rake db:schema:dump
Use git diff on schema.rb to compare the changes. This can easily be mapped to a migration.
The benefit of using source control is that you can then test the migration by comparing schema.rb after the migration runs to the schema dump of the second database.
Related
I am trying to find the correct (any) method to create an application in Ruby on Rails having an existing database (PostgreSQL) with data and fresh app made with:
rails new --database=postgresql -J --skip-coffee .
I found https://github.com/frenesim/schema_to_scaffold but first I need to have a file with a database structure: schema.rb. I’m looking for a way to do it automatically.
In result of rake db:schema:dumpfile schema.rb is generated, but only with content like that:
ActiveRecord::Schema.define(version: 0) do
enable_extension "plpgsql"
end
And I stuck here. Why that file is empty? Why are there no tables here?
I have a connection with DB and no errors. I did rake db:create before to test. Creation of bases described in database.yml is successful.
At the beginning I used Docker containers and this is my goal. But to exclude the probability of error, I installed the environment in the system (macOS Mojave) based on the socket. And I’ve got the same effect.
How to generate schema.rb with structure of existing database? Or is there different way to build RoR app based on the existing data structure?
Update: Connection with the new database I only did for testing purposes. To verify configuration.
Here's what else I did:
Dump existing structure with
pg_dump --schema-only app_development > db/structure.sql
I changed name in database.yml to have fresh place to import.
rake db:setup created new DB
rake db:structure:load create tables from db/structure.sql file in DB correctly.
But rake db:schema:dump still generate empty file as earlier.
If you have set proper db config you can use rake db:migrate to regenerate the schema file.
edit:
Ok so lets check if I understood correctly:
you have an existing db with tables and data in it
you have brand new rails app
you want to reflect db structure in you schema.rb file
Is that correct? If yes then like I wrote before - without adding any new migrations to your codebase, run rake db:migrate. That task not only applies changes from the migration file but also updates your schema file to be in sync with the actual database.
I've got it! Two days of my life.
File used to import PostgreSQL database has at the beginning:
CREATE SCHEMA employees;
-- and later
CREATE TABLE employees.department;
I thought that since Rails generates database by rake db:structure:load , the file's syntax is correct.
But when I create manually table users in new empty database and then pg_dump that new base I don't have CREATE SCHEMA query there.
And finally rake db:schema:dump fills schema.rb with tables as I want:
create_table "users", id: :serial, force: :cascade do |t|
t.text "name"
end
Because that fresh pg_dumped file has CREATE TABLE public.users query. public.
I think the key is in comments in database.yml file:
# Schema search path. The server defaults to $user,public
#schema_search_path: myapp,sharedapp,public
One picture is more valuable than a thousand words: that's the differences Table users on the right goes to schema.rb after rake db:schema:dump
Thanks guys for the comments. It's made sure me that I do not make a terrible mistake.
It sounds like you did rake db:create which creates a new database for you and then did rake db:schema:dump which generated a schema.rb file for you from the newly created (empty) database.
If you have an existing database that you want to use you will need to modify your database.yml file to connect to it.
If you want to create a new database you will need to generate Active Record database migrations e.g.) rails generate migration CreateProducts name:string part_number:string and then run them rake db:migrate to update your database and generate your schema.rb.
Every time I commit code that has a migration, for some reason, I get a bunch of schema changes that I didn't write, that came from previous PRs.
For example, i'll write a migration to add a column on User...but after running the migration, the schema file will include 10 changes from previous old code that isn't in the current branch at all.
How do I fix this?
The schema file reflect to the database schema. I think you had changed the schema at previous old code but didn't recover(rollback) it, deleted it and start coding for new migration.
The thing you shloud do is eliminating diff between code and datebase.
Solution:
Checkout to your old branch and rollback the schema change by runningrake db:migrate:down VERSION=20161106xxxxxx.
or
In current branch, run rake db:rollback STEP=n rollback schema change done by current branch
Then checkout co old branch execute rake db:rollback STEP=m to rollback schema change by old branch.
Checkout back to current branch, and run rake db:migrate, and you will not see the extra changes in schema file.
reference:
http://edgeguides.rubyonrails.org/active_record_migrations.html#rolling-back
http://edgeguides.rubyonrails.org/active_record_migrations.html#running-specific-migrations
There are two possibilities:
You haven't deleted the code for the previous migrations that you are trying to neglect from the schema.rb file.
You're very new to rails and you tried deleting fields from the schema.rb file manually, thinking it would synchronize with your database.
Either way: delete all the migration files you don't want if you haven't already, then simply rollback your database to the original empty version using the command:
rake db:rollback VERSION=0
Then: Now that you have the right migration files, migrate to your databse using the command:
rake db:migrate
This should give you an accurate schema.rb file
I am deploying a rails app to nginx.
There are many migrations in the development stage.
How to create the production schema in a simple way instead of reading many migration.rb files ?
Because I deleted several migration files during develepment. Now when deploy production environment it shows me some errors
Thanks
You can use the schema.rb file (via rake db:schema:load), but beware it will drop all existing tables. If you have existing data you will lose it.
Once you load the schema then it sets the database version, so only new migrations that are created after the schema file was created will run in the future.
Here is some info for Rails 4.2 about schema dumping:
Schema Dumping and You
I'm working on a rails application where we made changes to the schema directly without writing migration files. Now I want load the schema in the development machine to Staging server. But if I did rake db:schema:load, It will erase the data in the database.
Is there anyway to solve this problem? I want to restore the data in the table after running rake db:schema:load.
Is there a good way to merge rails db migration files into 1 file per table besides splitting schema.rb manually?
Most of my migration file was created during development and does not represent real data changes. For historical reasons those files will be still accessible on source control system. I feel uncomfortable keeping those unnecessary files.
Well, i can imagine that you want to have a clean start. While being in project development mode for your first version release you don't want all the separate migration files. Although they can't hurt obviously.
Basically what you can do, is this.
FIRST BACKUP your schema and data.
The db/schema.rb contains (or should contain) the latest version of your schema. Otherwise run:
rake db:schema:dump
Now you can clean your migration folder.
Then run:
rake db:drop
rake db:schema:load
The last command runs the db/schema.rb and create a new schema. This should bring you to the last version of your database.
show db task
rake -T db
You can use Squasher gem to merge the migrations all olds into one.
Don't bother. The old migration files are not doing any harm, and they may make maintenance easier. Leave them as they are.