0

I have a MySQL Database named Foo_development. It has one table, named bars.

$ mysql -e 'select * from Foo_development.bars'

+----+-------+---------------+---------------------+---------------------+
| id | name  | email         | created_at          | updated_at          |
+----+-------+---------------+---------------------+---------------------+
|  1 | Alice | Alice@bob.com | 2015-08-24 13:45:11 | 2015-08-24 13:45:11 |
+----+-------+---------------+---------------------+---------------------+

I'd like to create a Rails app that uses this database and this table. So I created an app and a model:

$ rails new Foo -d mysql
$ cd Foo
$ rails generate model Bar name:string email:string

That all worked just fine, although I had to edit config/database.yml to connect to the appropriate MySQL host before generating the model.

I tried running my app and got an error:

$ rails server

ActiveRecord::PendingMigrationError
Migrations are pending. To resolve this issue, run:
    bin/rake db:migrate RAILS_ENV=development

I tried running the migrations and got another error:

$ rake db:migrate

== 20150824204923 CreateBars: migrating ===
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'bars' already exists

Didn't know what to do here, so I tried something I found on Google:

$ rake db:migrate:reset

== 20150824204923 CreateBars: migrated (0.0124s) ===

But now all my database data is gone :(

$ mysql -e 'select * from Foo_development.bars'

Empty set (0.00 sec)

What should I have done instead to avoid losing all of my data?

I'm assuming there must be some command besides rake db:migrate:reset that would allow me to run the migrations without truncating the tables in the database, but I haven't found any.

I did look at these questions but they don't talk about preventing data loss, so this is not a duplicate.

If it matters, the Rails app is running from a different computer than the one which hosts the MySQL database. I'm trying to avoid import/export operations, because the databases that I'm working with (outside of this trivial example) have a million+ rows, but I suppose I'm willing to do that if that's the fastest method.

Edit: This question is similar, but it asks about sqlite3 and the answer involves importing the database from an external file (and I'm guessing there's a faster/more efficient way than that.)

Community
  • 1
  • 1
m81
  • 2,217
  • 5
  • 31
  • 47
  • Hi @mchenja! Were you able to resolve your question? – Papouche Guinslyzinho Aug 25 '15 at 01:10
  • Haven't tried yet; still hoping for a solution that doesn't require importing/exporting. – m81 Aug 25 '15 at 01:11
  • Then you can copy the `db/*` folder to your new app. then run a rails server. that should be ok – Papouche Guinslyzinho Aug 25 '15 at 01:14
  • I'm not sure I understand - where would I get this folder from? There is no "old" app – m81 Aug 25 '15 at 01:15
  • sorry I touch Foo_development was from a rails app. Then I think @They_Call_Me_Joe offers a great solution. But you will need to export/import. Cause you won't be able to do it straight. Rails require a **migrations** table that will contains all the version of your db. Unless that you create manually this table, add a content to it, and create also manually a `schema.rb` file – Papouche Guinslyzinho Aug 25 '15 at 01:34
  • @PapoucheGuinslyzinho there's no way to create the migrations table automatically without deleting/truncating existing tables? – m81 Aug 25 '15 at 01:41

4 Answers4

1

In your first Rails app (the old one) you can add the gem seed_dump https://github.com/rroblak/seed_dump in your Gemfile then bundle install

then run in rake db:seed:dump db:drop that will dump the content of your database in your db/seed.rb file and that will also drop your db. Then you can copy and paste this file into your new Rails app under db/seed.rb.

`rake db:create`#create the db (database.yml)
`rake db:migrate db:seed`

So at the end you recreate a db with the same content. Notes if you want only one table you can use rake db:seed:dump MODELS=Bar

edit

First check to see if you have the program mysqldump installed on your machine

which mysqldump

If so then

mysqldump your_database_name > output.sql

In your rails app

rake db:drop db:create db:migrate

Make sure that you drop the db either by rake or by sql syntax.

open the file output.sql and add the line that start with INSERT INTO bars.... in your `db/seeds.rb``with this following syntax.

sql = "INSERT INTO `friendly_id_slugs` VALUES (3,'abram-s-commitment-to-a-life-of-faith',1,'Book',NULL,'2015-08-27 01:50:39'),(4,'what-aileth-thee',2,'Book',NULL,'2015-08-27 01:50:39');"

ActiveRecord::Base.connection.execute(sql)

Notes you might have to edit your sql variables to use proper apostrophe ' or ". You could also rails c -s and execute the above code manually to see if it works on the sandbox console

Then finally

rake db:seed
Community
  • 1
  • 1
Papouche Guinslyzinho
  • 5,277
  • 14
  • 58
  • 101
  • I did try this, but unfortunately the `seed_dump` gem doesn't keep track of id's for each model. [Issue on GitHub](https://github.com/rroblak/seed_dump/issues/87) – m81 Aug 26 '15 at 23:09
  • Ok look at my **edit** ... if it works. I will delete the first part of my answer... the one before the **edit**. I do prefer the **seed_dump** gem not to take track of my **id** number. – Papouche Guinslyzinho Aug 28 '15 at 01:06
  • I actually think both parts of your answer are useful, so I wouldn't delete anything if I were you. But I will try it! – m81 Aug 28 '15 at 01:17
1

A simple option would have been to put your CreateBars migration version number into the schema_migrations table.

It appears that the migration file that was causing trouble is probably named db/migrate/20150824204923_create_bars.rb, right?

So you could have done this in your database since the table was already there:

INSERT INTO schema_migrations(version) VALUES('20150824204923');

Oh, and I suppose you'd probably need to create the schema_migrations table too since Rails probably hadn't done that either:

CREATE TABLE IF NOT EXISTS schema_migrations(
  version VARCHAR NOT NULL
);
Chris Peters
  • 17,918
  • 6
  • 49
  • 65
0

I would export the tables in the database as a .csv file, depending on the language, framework, etc. you are using it is done in different ways.

Then you could fill your database seeds in your rails application from that csv file.

There are several gems that do that, please find a great one below:

https://github.com/tilo/smarter_csv

They_Call_Me_Joe
  • 194
  • 1
  • 11
0

As there is only one table, the easiest way would be to take a backup of the database. Create the app, create new migrations, then restore the table from the backup.

margo
  • 2,927
  • 1
  • 14
  • 31