William Graham’s blog

July 1, 2008

Altering the way Rails migrations create Oracle sequences

Filed under: Oracle,Programming,Ruby on Rails,Web Development — liamgraham @ 7:04 pm

Lately I’ve been using Ruby on Rails for a project at work, and am really enjoying it. Several things bug me about managing an Oracle database with migrations, though. The main one that just struck me as bizarre is how each table’s sequence is created with a starting value of 10,000. Why? Where did that number come from, who came up with it, and why is there not a way to override it within the migration, short of using execute to drop the sequence after the fact and recreate it (since you can’t change an Oracle sequence’s starting value with an alter statement).

I dug into the code for the OracleAdapter, and sure enough, there it is, right there in the create_table method:

def create_table(name, options = {}) #:nodoc:
  super(name, options)
  seq_name = options[:sequence_name] || "#{name}_seq"
  execute "CREATE SEQUENCE #{seq_name} START WITH 10000" unless options[:id] == false
end

I was all set to just modify the CREATE SEQUENCE code above when my coworker Greg Donald, who knows much more about Ruby and RoR than I do, knocked me out with yet another in the long line of things about Ruby on Rails that make me yell “Sweet!” Thanks, Greg!

Within your Rails app’s environment.rb file you can override code. Simply by putting this snippet at the bottom of the file, I was able to change the way migrate creates my Oracle sequences:

module ActiveRecord
  module ConnectionAdapters
    class OracleAdapter
      def create_table(name, options = {}) #:nodoc:
        super(name, options)
        seq_name = options[:sequence_name] || "#{name}_seq"
        execute "CREATE SEQUENCE #{seq_name} START WITH 1 NOCACHE" unless options[:id] == false
      end
    end
  end
end

Notice that I also added in NOCACHE while I was at it, to prevent Oracle from grabbing 20 sequence values at a time.

This is just cool. Without having to keep track of custom changes made to the adapter, which could be lost with future upgrades, and without having to resort to a bunch of execute statements within the migration file to drop and recreate the sequences, I’m able to get the custom behavior that I need. Honestly, of course, I think that the starting value should default to 1, not 10000, and I wish that something like NOCACHE was an option that could be passed. But this gets me what I need, and I can see this sort of override capability coming in very handy for other Rails customizations.

Now on to adding something to support bitmap indexes! 🙂

Advertisements

2 Comments

  1. Cool.
    I had this exact same problem!
    Thanks for the code snippet =)

    Cheers
    Dave Smylie

    Comment by Dave Smylie — March 8, 2009 @ 8:57 pm

  2. Hi,

    Nice post. I would take it one step further and chop the #name to the first 26 characters. That way you avoid the possibility of a sequence name longer than 30 characters.

    Regards,

    Dan

    Comment by Daniel Berger — September 9, 2009 @ 10:58 pm


RSS feed for comments on this post.

Blog at WordPress.com.

%d bloggers like this: