rake db:test:purge creates mysql database with wrong charset & collation #1952

merged 1 commit into from Jul 6, 2011


None yet

2 participants


In db:test:purge ActiveRecord::Base.connection.recreate_database is called with the full database config options hash instead of the :charset and :collation hash that is expected.

This causes my test database to be created with the collation set incorrectly (I need utf8_bin) and my fixtures don't load and my tests fail. (Further explanation in comments).

See new method mysql_creation_options. It is used by both create_database and recreate_database so they are consistent.

@simonbaird simonbaird Fix charset/collate in mysql recreate_database
See new method mysql_creation_options. It is used by both
create_database and recreate_database so they are consistent.

An alternative fix might be to change the options param here:

 create_database(name, {:charset => options['charset'], :collation => options['collation']})

but that would ignore ENV['CHARSET'] and ENV['COLLATION']


More explanation

Imagine if you set charset and collation in config/database.yml. For this example lets use the test db:


  adapter: mysql
  database: myapp_test
  username: root
  host: localhost
  charset: some_charset
  collation: some_collation

Now run

RAILS_ENV=test rake db:create

it calls create_database with these options:

{:charset=>"some_charset", :collation=>"some_collation"}

This is correct and creates the database with the correct charset and collation.

Now if you run

rake test

it calls recreate_database which then calls create_database with the following options, (ie the entire test db config from database.yml):

{"username"=>"root", "adapter"=>"mysql", "charset"=>"some_charset", "database"=>"myapp_test", "host"=>"localhost", "collation"=>"some_collation"}

Notice that it does have the collation and charset values there BUT the hash keys are symbols so there is no options[:collation] and no options[:charset] present. This causes the database to be created with the default charset of utf8 and an unspecified collation.

(See create_database method here:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb#L520 )


In my particular case using the default collation value causes the primary key constraint to consider primary keys as case insensitive, which means I can't load fixtures since I have some data where primary key constraints need to be case sensitive.

It's not hard to imagine other scenarios where having the test database created with a different charset and collation when running tests could lead to weirdness and problems.

The patch

It would be simple to patch recreate_database to work-around this (see comment above), but ideally we should respect the ENV['CHARSET'] and ENV['COLLATE'] values in the same way that rake db:create would do. So the fix is done in database.rake and involves a small refactor so create_database and recreate_database can work the same way.

In Rails 3.1

I have not confirmed it but from looking at the code I believe this problem exists in the 3.1 stable branch also. A port of this fix to 3.1 might be required if this doesn't merge cleanly.


Changed name to be more descriptive.

@spastorino spastorino merged commit 2f3eb7a into rails:3-0-stable Jul 6, 2011

can you provide the same pull requests for 3-1-stable and master please?


Okay, done.


They are different commits but identical diffs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment