Rails, PostgreSQL, and database drivers 5
There are a variety of database drivers available for getting a Rails app to talk to PostgreSQL. The Rails wiki has an excellent overview of the various drivers and their freshness. Here's a summary:
gem install postgres-pr: This gets you the pure Ruby driver - e.g., no native code. Thus it is slow. It's useful if you don't have a native PostgreSQL client, though. I actually use this on RubyForge - I didn't know any better when I first wrote code using it and now I need to go back and remove it.gem install postgres: This gets you a native driver, but it's over 18 months old. Don't use it. If you are already using it, however, it looks like PostgreSQL guru Jeff Davis is doing bugfixes as necessary. So, you could do worse.gem install pg: This is the one! This gets you a native driver that's actively being maintained. It's a complete rewrite of thepostgresdriver and is the way to go.gem install activerecord-jdbcpostgresql-adapter: I haven't used this, but Simon Tokumine recommends using this gem if you're using JRuby with Rails and PostgreSQL. From the ActiveRecord-JDBC project site, this gem "[...] allows use of virtually any JDBC-compliant database with your JRuby on Rails application". Sounds like a winner.
Here's an edge case I ran into recently. I had a Rails 2.0.2 application in production, and ActiveRecord 2.0.2 does a require _library_or_gem 'postgres' in activerecord-2.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb, so it won't work with the pg gem. If you're stuck on Rails 2.0.2 for some reason you'll need to go with either postgres or postgres-pr. You could try hacking the adapter to work with pg, but I went down that road, made three or four changes, kept getting errors, and decided it was just simpler to use one of the older gems. I'd be interested in hearing from anyone who's modified that version of the adapter to use the new driver... although the better path is probably just to upgrade the application to use a newer version of Rails.
Also, for folks upgrading to Snow Leopard, here's a helpful post on the pg gem and ARCHFLAGS from Jan.
To underscore my recommendation to use the pg gem, here's a quote from that project's README:
The 'pg' module is the newer module, that has been greatly improved, and is almost a complete rewrite. It is not backwards compatible. Use this module for newly written code. It should be more stable, less buggy, and has more features.
Indeed.
I poked around the code of pg and postgres to see the differences. It looks like a lot of cleaning up has happened. For one example, the PQfreemem function that libpq provides isn't being used in pg since, per line 27 of pg.c, "[it's] unnecessary: copied to ruby object, then freed. Ruby object's memory is freed when it is garbage collected." A quick grep around the postgres gem shows a bunch of occurrences of that function - it was even embedded in a preprocessor directive to make it easier to use.
So, to sum up, gem install pg. Thanks to Jeff for his work on this!




Great website! Is the new pg driver much faster?
@alex, Thanks! I haven’t seen any benchmarks… but it’s definitely the way to go.
On OSX (Leopard), this is the process I used to get the native gem to build…
Note that the postgres bin path is specific to my installation.
You do not need to install gems as root. If the reason is “because then the command shows up” then add the user’s gem directory to your path:
You can even set this exclusively:
For the purposes of pg gem, in order to cover both bases (both 32 & 64 bit compiled postgres installs) on OSX:
Ensure that your path has psql in it as noted above. Change /opt/local/lib/postgresql83/bin to wherever you have pg_config located. For me this is:
Then install the gem.
This non-root technique is especially useful when you have multiple ruby versions installed and are actively switching/using all of them ( I use rvm for this http://rvm.beginrescueend.com/ )
w00t for Postgres!
@wayne, true… I guess that most of the time when I install a gem, though, I want it to be available to all user accounts on the box. But you’re right, another possibility is to just install it to your home directory.