I have some raw sql statements that create triggers and functions in my migrations. They are not invoked in the tests.
How can I use normal migrations to setup the test database? And why isn't that the default method?
Reason is that the test database is restored from schema.rb file. And Schema dump doesnt create procedures,functions, fkeys etc. The reason for that is Rails doesnt encourage using them. You can however change the schema dump format to sql.
config.active_record.schema_format = :sql
See following thread Why does rake db:migrate in Rails not add functions to the schema file?
Check this article as well http://pivotallabs.com/users/jdean/blog/articles/1707-using-mysql-foreign-keys-procedures-and-triggers-with-rails
Related
Is the structure just a sql version of the db while the schema is a Rails version of the db? When would you want to load either? Or does it make a difference?
The schema file is the Rails version of your db and doesn't contain any db specific stuff like, views, triggers, and so on.
db/schema.rb cannot express database specific items such as triggers,
sequences, stored procedures or check constraints, etc. Please note
that while custom SQL statements can be run in migrations, these
statements cannot be reconstituted by the schema dumper. If you are
using features like this, then you should set the schema format to
:sql.
http://edgeguides.rubyonrails.org/active_record_migrations.html#schema-dumping-and-you
When would you use one over the other depends on whether you have db specific stuff that you need. If all you use are the basic tables, with indexes and primary and foreign keys you are good to go with schema files.
In my opinion however I always use structure.sql since I always use some db specific things.
You can change what format you want to use by changing this in your config/application.rb file.
config.active_record.schema_format = :sql # default is :ruby
I have some custom functions and triggers, that were run as migrations and added into dev db. However when i run my tests - it seems like test db doesn't have these functions and triggers, and throws errors in specs, which using queries that requires these db-functions. I've tried to manually run
rake db:test:clone - but that copies only db structure, not its functions and triggers. How do i create full duplicate for db, keeping not only its structure, but also custom db functions, triggers and views?
PS: Db: postgres
I recommend you use this setting:
config.active_record.schema_format = :sql
This would create a real sql file containing all details of your db.
And it would be loaded whenever you use rake db:setup
Before changing the setting, you could use rake db:structure:dump to create the sql file.
I have an application that requires a sequence to be present in the database. I have a migration that does the following:
class CreateSequence < ActiveRecord::Migration
def self.up
execute "CREATE SEQUENCE sequence"
end
def self.down
execute "DROP SEQUENCE sequence"
end
end
This does not modify the schema.rb and thus breaks rake db:setup. How can I force the schema to include the sequence?
Note: The sequence exists after running rake db:migrate.
Rails Migrations because they aim toward a schema of tables and fields, instead of a complete database representation including stored procedures, functions, seed data.
When you run rake db:setup, this will create the db, load the schema and then load the seed data.
A few solutions for you to consider:
Choice 1: create your own rake task that does these migrations independent of the Rails Migration up/down. Rails Migrations are just normal classes, and you can make use of them however you like. For example:
rake db:create_sequence
Choice 2: run your specific migration after you load the schema like this:
rake db:setup
rake db:migrate:up VERSION=20080906120000
Choice 3: create your sequence as seed data, because it's essentially providing data (rather than altering the schema).
db/seeds.rb
Choice 4 and my personal preference: run the migrations up to a known good point, including your sequence, and save that blank database. Change rake db:setup to clone that blank database. This is a bit trickier and it sacrifices some capabilities - having all migrations be reversible, having migrations work on top of multiple database vendors, etc. In my experience these are fine tradeoffs. For example:
rake db:fresh #=> clones the blank database, which you store in version control
All the above suggestions are good. however, I think I found a better solution. basically in your development.rb put
config.active_record.schema_format = :sql
For more info see my answer to this issue -
rake test not copying development postgres db with sequences
Check out the pg_sequencer gem. It manages Pg sequences for you as you wish. The one flaw that I can see right now is that it doesn't play nicely with db/schema.rb -- Rails will generate a CREATE SEQUENCE for your tables with a serial field, and pg_sequencer will also generate a sequence itself. (Working to fix that.)
I wrote a Mysql function for my rails app and i added it to my database by manual.
When i want to test the function using Rails UNIT test, it through the errors like below
ActiveRecord::StatementInvalid: Mysql::Error: FUNCTION mydatabase.fn_Sample_Function does not exist:
How to add the function, out of the test suite or beginning of test run ?
Thanks in Advance,
Aaa.
I can't see the error. But I assume the problem is your schema format.
config.active_record.schema_format = :sql
in application.rb should be what you need to do.
The reason behind that is by default your test database is not made from a schema only dump of your development database, but, instead from db/schema.rb - which knows nothing about mysql functions.
an sql schema format will do a mysqldump (or pg_dump) with the schema only flag set to true and create a development_structure.sql file.
As per http://edgeguides.rubyonrails.org/configuring.html and this post I have this in application.rb
config.active_record.schema_format = :sql
However, it's still creating db/schema.rb (even after I delete it) and more importantly it's not creating the schema in sql when I run "rake db:migrate". Anyone know what I'm doing wrong? I'm on Rails 3.1 pre.
Well, this could be a rails bug, but you can always generate your db structure with this:
rake db:structure:dump
This is going to generate an "#{Rails.env}.sql" file for you with your database structure in SQL.