Wednesday, December 16, 2009

Dealing with "rake aborted! uninitialized constant MysqlCompat::MysqlRes"

This post is relevant for those running Ruby on Rails and MySQL on Leopard or Snow Leopard using the default components pre-installed in OS.  This will probably be relevant to those who have a Hive Logic roll your own from source install also.    This post might even be useful to those daring enough to do their RoR work on Linux, go Penguin Heads!

Ok, I am creating this post for those that have the misfortune of running into this error as I have.  I am not a rails noob, but I am far from a jedi, so when I run into problems I usually turn to web forums and blogs for solutions.  The only problem is there is often lots of solutions to the same problem with very little explanation as to why the solution works or a way to derive at the conclusion that the offered suggestion is in fact a solution.

That is my attempt to avoid that here.  If you are getting the dreaded "rake aborted! uninitialized constant MysqlCompat::MysqlRes" when trying to run a rake db:migrate command on your rails project their is a reason.  The reason is not Rails, and not MySQL but the mysql gem you have installed into Rails.   Basically you have installed the mysql gem incorrectly.   Luckily there is a simple trick to determine the correct method to install your mysql gem.

Since the MySQL database you installed on your OSX of some feline distinction is not a universal binary it is architecture specific.  Thus the mysql gem must also be compiled by the gcc compiler to match the same architecture.   So you have to determine the correct command and architecture to use to install the mysql gem.  I will lay out the simplest solution that I know of to correctly determine the command for yourself.

1. Open a terminal window,  btw if you need a tutorial on how to do this welcome to the unix world and don't feel bad we all have to start somewhere ;)

2. Navigate to some benign place like your desktop for example:

cd ~/Desktop/

3.  Create a simple Rails demo project with the specification for a MySQL database with the command:

rails demo --database mysql

4.  Now you need to navigate to the config folder of your project by running the command:

cd demo/config/

5. Once in the config directory running the ls command should return results like below :

Machinename:config username$ ls
boot.rb environment.rb initializers routes.rb
database.yml environments locales

6.  Use your favorite text editor to view the contents of the database.yml file, my favorite is Textmate but for convention I will us the command for vi since most folks have vi even if they don't have Textmate.

vi database.yml

7. ***IMPORTANT***  Before running any of the below commands you need to clean out any mysql gems you have already installed using the command in a terminal window after closing vi or the text editor you use to view the database.yml file

gem uninstall mysql

if given options for multiple mysql gems REMOVE THEM ALL.

8.  Inside the database.yml file you should see something similar to the text below:

Install the MySQL driver:
#   gem install mysql
# On Mac OS X:
#   sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql
# On Mac OS X Leopard:
#   sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
#       This sets the ARCHFLAGS environment variable to your native architecture
# On Windows:
#   gem install mysql
#       Choose the win32 build.
#       Install MySQL and put its /bin directory on your path.

9. Notice the command for Leopard, this is **ALMOST** the command I needed to use to install the mysql gem into rails.  The reason I say almost is there was one minor change that I needed to make. You have to set the correct architecture type in the ARCHFLAGS specification.  If you are like me and Santa hasn't brought you a new powerbook in the past few years then it maybe "- arch ppc".  If you have been good then Santa may have you on the "-arch i386" arch type and if you have been really nice you may get to use "-arch x86_64" so below are the different commands for the different feline distros, but remember to clear out any already installed mysql gems first (see step 7 above).

Prior to Leopard:
sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

Leopard on a PPC machine:
sudo env ARCHFLAGS="-arch ppc" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Leopard on an Intel machine:
sudo env ARCHFLAGS="-arch i386" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Snow Leopard (only on Intel):
sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

10.   That should do it.  You should now be able to return to your projects and run the rake db:migrate command without seeing the awful  "rake aborted! uninitialized constant MysqlCompat::MysqlRes"  error.

11. Many thanks to my Ruby on Rails Jedi friend RW for showing me this simple trick.  The force is powerful in that one :)



26 comments:

  1. Thanks for your post.
    I've followed the Hivelogic instruction and successfully installed the mysql 5.1.41. I've updated all my gems, including Rails to 2.3.5.
    I've deleted all of my mysql gems and reinstalled it with your Snow Leopard (only on Intel) snippet for my 13'' MBP.

    [demo] $ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
    Building native extensions. This could take a while...
    Successfully installed mysql-2.8.1
    1 gem installed

    When I try to run rake db:migrate:

    rake aborted!
    uninitialized constant MysqlCompat::MysqlRes

    I am with that for about 6 hours now and it just frustrates me.

    Installing mysql version 2.7 via
    [demo] $ sudo env ARCHFLAGS="-arch x86_64" gem install -v=2.7 mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

    it get's me a a rake db:migrate error like:
    dlopen(/usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.bundle, 9): no suitable image found. Did find:
    /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.bundle: mach-o, but wrong architecture - /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.bundle

    I have installed mysql from scratch via Hivelogic. Did a lot of googling but I can't find the error on that. Might it be the PATH in my .profile:
    export PATH="/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:$PATH"

    Any ideas what could help me?

    ReplyDelete
  2. Another couple of hours and I got it fixed.
    The problem seemed to be a 32bit Ruby version I totally overlooked.
    So I ran through the Hivelogic Snow Leopard Ruby installation process and did it manually. Once I had my 64bit Ruby everything went well!

    ReplyDelete
  3. I much appreciate this generous post. However, I still get the unfortunate error of 'uninitialized constant MysqlCompat::MysqlRes'.
    I have been working on this on and off over several days now, and have examined many other posts regarding this diabolical error (even upgraded to Snow Leopard last weekend trying to fix this). But this place seemed like a good place to seek help.

    I will state that I'm new to Ruby on Rails, but have been working 15 years as a database programmer, with Linux about 10 years, but only converted to an Mac in the past year (and I'm never going back!). So I'd like to learn more about how to diagnose this error, so I can fix my own problems in the future.

    To state my case: I have an iMac w/ Intel Core 2 Duo (which I believe means I have 64 bit architecture); other data:
    ruby --version
    ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9.8.0]
    gem --version
    1.3.5
    rails --version
    Rails 2.3.5
    mysql --version
    mysql Ver 14.14 Distrib 5.1.42, for apple-darwin10.0.0 (i386) using EditLine wrapper


    I'm trying to work through the example at developer.apple.com, using the 'expenses' example.

    Here is the latter parts of the trace of the error when I try to do 'rake db:migrate' (earliest portion truncated to make it fit):

    uninitialized constant MysqlCompat::MysqlRes
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:440:in `load_missing_constant'
    /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:80:in `const_missing'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/mysql_adapter.rb:9:in `define_all_hashes_method!'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/mysql_adapter.rb:68:in `mysql_connection'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `send'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:223:in `new_connection'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/connection_pool.rb:245:in `checkout_new_connection'

    ...
    /usr/local/bin/rake:19:in `load'
    /usr/local/bin/rake:19


    I would deeply appreciate any insights to my error, how to diagnose it further.

    Best regards,
    Rick Casey

    ReplyDelete
  4. Thanks, I have been hunting for this for a while now, and this got it.

    ReplyDelete
  5. Thank you so much! That part for snow leopard was just what I needed. "-arch x86_64"... of course!

    ReplyDelete
  6. thanks for your detailed instructions. having mysql installed via homebrew, i had to use

    --with-mysql-config=/usr/local/bin/mysql_config

    but then it worked perfectly for me.

    ReplyDelete
  7. This worked great, thanks for the post!

    ReplyDelete
  8. you are a pimp! thx a lot... had this issue for a long time and I didn't have the time to investigate a lot... your article fixed the issue for me :)

    ReplyDelete
  9. Thanks a ton.....worked perfectly for me :)
    Have posted your page to StackOverflow as well.

    ReplyDelete
  10. This worked "almost perfectly" for me. Setting up a "Mac mini Server" (the $999 version) which has OS X Server 10.6 installed, the path is different.

    The correct install path is: /usr/bin/mysql_config

    Also, the Apple KnowledgeBase article TS25017 states "MySQL client libraries and headers are not included with Mac OS X Server 10.5" -- they aren't included with OS X Server 10.6 either, as I had to follow the links on that page and install the header files before the developer could proceed.

    ReplyDelete
  11. Oh, I almost forgot to mention; the instructions on that KnowledgeBase page are for an older version of MySQL. If you are "less than totally familiar" with all this command line stuff (as I am) be sure to insert the current version file name (MySQL-53.binaries.tar.gz for OS X 10.6.3) in Step 6.

    ReplyDelete
  12. Thanks for helping me keep my hair!

    ReplyDelete
  13. Thanks mate - much appreciated!

    ReplyDelete
  14. Thank you very much for you!!! It helped me...

    ReplyDelete
  15. If you installed mysql in a non-standard location (e.g. $HOME/local/mysql), you have to add this location to your LD_LIBRARY_PATH or DYLD_LIBRARY_PATH for mac. I have added the following to my ~/.bashrc

    export DYLD_LIBRARY_PATH=$HOME/local/mysql/lib:$DYLD_LIBRARY_PATH

    ReplyDelete
  16. Thanks a bunch, this worked perfectly.

    ReplyDelete
  17. I needed to do both:

    $ sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

    and add


    export DYLD_LIBRARY_PATH=$HOME/local/mysql/lib:$DYLD_LIBRARY_PATH

    to my .profile before I could get rake to work. Thanks for the post.

    ReplyDelete
  18. Thanks a lot for this useful post! :-)

    ReplyDelete
  19. This comment has been removed by the author.

    ReplyDelete
  20. Just a heads up: I had to use the following on a MacBookPro using SnowLeopard:

    sudo env ARCHFLAGS="-arch x86_64" gem install mysql -- --with-mysql-config=/usr/local/bin/mysql_config

    basically, mysql_config was in another place.

    ReplyDelete
  21. I was running rails on my linux (debian) machine when I met this error. I was using RVM to manage ruby and my ruby gems.

    It turns out the error was because my mysql gem wasn't getting installed properly. The reason to that was because I was missing libmysqlclient-dev

    found it from here: http://stackoverflow.com/questions/1857059/cant-install-do-mysql-gem

    Just installed the missing package by running:
    sudo aptitude install libmysqlclient-dev

    ..and it fixed it for me. one for the penguins! :)

    ReplyDelete