Want to use PostgreSQL’s native UUID datatype but AR won’t let you use it with migrations?
/Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/postgresql_adapter.rb:
# insert into def simplified_type # UUID type when /^uuid$/ :uuid # insert into def native_database_types :uuid => { :name => "uuid" },
Well, that’ll get your data OUT of the database, but AR will throw a fit when you try to load it back in unless you also add uuid into the range of column types TableDefinition will accept:
in /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2
/lib/active_record/connection_adapters/abstract/schema_definition.rb:
# insert into def column(name, type, options = {}) %w( string text integer float decimal datetime timestamp time date binary boolean uuid ).each do |column_type|
Now you can do this:
t.uuid "uuid", :null => false
About the nastiest possible hack you can do but works in/out. Here’s a patch if you don’t want to do it yourself, but no guarantees.
UPDATE:
And don’t forget to write your migrations like this to stop AR from inserting its “helpful” id columns with autoincrementing serials which your DB doesn’t need and can’t use:
def self.up create_table :transactions, :id => false do |t| t.uuid "id", :null => false t.timestamps end end
UPDATE 2:
I now do not recommend doing this. It’s more trouble than it’s worth. There is very little you gain in forcing native UUID type in Postgres, and the complexity, hacks, loss of cross-platform compatibility and general annoyance you face are just not worth it.
Just use a string class for any UUIDs. Of course, the final hint on this page – the no-id switch for migrations – is still useful and you should use that.
Tags: activerecord, datatypes, postgresql, schemadumper
April 2nd, 2008 at 11:42 am
[...] From Sho Fukamachi’s Blog: [...]
February 13th, 2009 at 11:01 pm
The backside of that technique, however, is that all lookups of your models require a string index in the database which is considerably slower than an integer index. Besides, adding an unique index on your table’s id wouldn’t hurt.
February 13th, 2009 at 11:06 pm
eno, do you have a benchmark to suggest an integer lookup is significantly faster than a string lookup? I didn’t think it was but I’m happy to be proven wrong.
Not that it matters – you can’t use integers anyway in this use case. The reason you use UUIDs is to enable multi master replication. With multiple machines, possibly on different continents, “unique” is useless, and trying to use an incremented integer ID is a nightmare. Unless you really, really need this though, definitely stick with autoincremented integer IDs.