Cucumber with Database_Cleaner for MySQL and MongoDB - mysql

I am building a Rails app that uses MySQL for some models and MongoDB for others (through the mongo_mapper gem).
We have started to build out cucumber (with capybara and webdriver) tests for the app and are coming across some trouble with IDs being referenced that don't exist. I believe I have tracked this down to old data in the MongoDB.
At this point, database_cleaner is doing its job with the MySQL records, but not the MongoDB ones.
There is a discussion at the cucumber-rails project about using MongoDB, but I believe it assumes that you are only using MongoDB, not both MongoDB and MySQL together.
Is there a way to have the database_cleaner clean both MySQL and MongoDB? Or is it only one or the other?
I found this article on how to drop all of the MongoDB content before running the tests, but I believe this will delete all data including the records I am using for local development...
Thanks.

Assuming you are doing something like this when you tell rails which Mongo DB to talk to:
MongoDatabase = "mongodb://localhost/yourdb_#{Rails.env}"
Then in your tests, do:
/spec/spec_helper.rb
MongoMapper.database.collections.select { |c| c.name != 'system.indexes' }.each(&:drop)
(above is for MongoMapper, but idea is the same for Mongoid -- just drop to the database level and drop all collections).
This will only drop data in your test database, not your dev db. Used in conjunction with the DB cleaner, you're good to go.

Related

Mongoose / Mongodb migration to MySQL

I have a NodeJS project running with mongodb database (using mongoose).
For a technological constraint reason I need to migrate the app from using mongodb to mysql - is there a way to migrate to mysql without having to rewrite the whole mongoose model files?
PS. although I'm using mongodb all the query is mainly still not on the nested document (I'm querying only by ID or by some first-level attribute) so actually putting nested document into a field in mysql table should still be fine
I would suggest letting your application run with Mongo for now. Meanwhile write a wrapper for MySQL that would translate your Mongo queries to mysql. Switch to that wrapper once done. Then write another wrapper for Mongo, just in case you need to switch back.
Try and keep all your Database specific function calls in the wrapper. So, that you won't need to do this again and again. Just write a new wrapper for whatever Database you will use and just switch.
And you'll probably need to run some sort of job to migrate your data from Mongo to MySQL.

Read existing mysql tables using Grails by generating the domains

I'm trying Grails 3.0.8 for the first time. I'll use it to create web-services for mobile development.
I already have a mysql database with a lot of tables. I found that I can use "db-reverse-engineer:0.5.1" to generate the different domains from the tables. For some reason, I cannot install the plugin and it doesn't work. I think it has something to do with the new version of Grails which is 3.0.8.
As there are not a lot of documentation on this version, I was wondering if there was a way to generate domains from an existing MySQL database.
If not, is it possible to use the database without having to create domains for the tables?
The db-reverse-engineer plugin is for Grails 2. It's not compatible with Grails 3. See Grails 3 reverse engineer database to domain objects
You can run database queries if you get a Hibernate session. You can read about how to get one here.
With a Hibernate session, you can use the Session.createQuery(String) method to create a SQLQuery instance. Then just execute the SQLQuery.list() method to run the query. Here's an example of running an arbitrary query in an H2 database.
def q = session.createSQLQuery 'select * from INFORMATION_SCHEMA.COLUMNS'
q.list() // Runs the query.

Migrating subsets of production data back to dev

In our rails app we sometimes have db entries created by users that we'd like to make part of our dev environment, without exporting the whole table. So, we'd like to be able to have a special 'dev and testing' dump.
Any recommended best practices? mysqldump seems pretty cumbersome, and we'd like to pull in rails associations as well, so maybe a rake task would make more sense.
Ideas?
You could use an ETL tool like Pentaho Kettle. Once you have initial transformation setup that you want you could easily run it with different parameters in the future. This way you could also keep all your associations. I wrote a little blurb about Pentaho for another question here.
If you provide a rough schema I could probably help you get started on what your transformation would look like.
I had a similar need and I ended up creating a plugin for that. It was developed for Rails 2.x and worked fine for me, but I didn't have much use for it lately.
The documentation is lacking, but it's pretty simple. You basically install the plugin and then have a method to_sql available on all your models. Options are explained in README.
You can try it out and let me know if you have any issues, I'll try to help.
I'd go after it using a Rails runner script. That will allow your code to access the same things your Rails app would, including the database initializations. ActiveRecord will be able to take advantage of the model relationships you've defined.
Create some "transfer" tables in your production database and copy the desired data into those using the "runner" script. From there you could serialize the data, or use a dump tool, since you'll be dealing with a reduced amount of records. Reverse the process in the development environment to move the data into the database.
I had a need to populate the database in one of my apps from remote web logs and wrote a runner script that fired off periodically via cron, ftps the data from my site and inserts the data.

Programmatic creation of MySQL database at runtime

Is there a way within Rails/AR to create a new mysql database at runtime?
What i recommend is to prepare standalone script readable only by specified user and execute it from rails with system command with db name as parammeter
The quick and dirty answer is:
Make sure the MySQL user your app is connecting as is allowed to create databases.
Create the database using a SQL statement:
ActiveRecord::Base.connection.execute('CREATE DATABASE IF NOT EXISTS new_database');
For simplicity's sake I'd suggest not even using ActiveRecord for this. AR is really designed to work with preconfigured databases, and even though you can create databases where you'll really run into problems is in trying to connect to and use those DBs on the fly.
You might be better off using Brian Lopez's mysql2 gem (in addition to AR for your app's main DB):
https://github.com/brianmario/mysql2
In addition to being pretty fast and modern, its API is a lot easier to work with than the raw mysql library (which is what AR uses under the hood, including connection.execute).

Rails/MySQL: Knowing a version number for a table, or the entire db schema

As an API endpoint, I need to provide a table schema with a version number so that the mobile developers I am working with can cache the schema until it changes again.
I am automating this process, which complicates the "versioning" idea.
At first I thought that I could use the latest migration number as the version # but it occurred to me that Rails migrations are non-sequential now, so it would mean that I would need to give them all migration numbers and they would need to decide if there was a new migration present by comparing the arrays (maybe this is the solution?)
I’m wondering if I am missing anything - if there is any other schema version number in Rails apart from those stored in the migration table, or also if there was any way of tracking this through mysql.
Using the migration version could be a good idea.
If you don't want to expose the full list of missing migrations, you can provide the current schema version for a quick comparison, then expose the full list on a second request.
You can obtain the list of pending migration using the ActiveRecord::Migrator object.
migrations = ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations
migrations.each do |migration|
migration.version
end
And for the current schema version.
schema = File.read("#{RAILS_ROOT}/db/schema.rb")
version = ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, schema)
puts version