jashmenn / activeuuid

Binary uuid keys in Rails
MIT License
340 stars 124 forks source link

t.uuid primary key migration creates sqlite_autoindex and schema:load fails #55

Closed luopio closed 9 years ago

luopio commented 9 years ago

I'm integrating Ahoy with Rails 4.2.0.beta2 and thus using the git version of activeuuid. Given this migration:

class CreateAhoyEvents < ActiveRecord::Migration
  def change
    create_table :ahoy_events, id: false do |t|
      t.uuid :id, primary_key: true
      t.uuid :visit_id
      t.integer :user_id
      t.string :name
      t.text :properties
      t.timestamp :time
    end

    add_index :ahoy_events, [:visit_id]
    add_index :ahoy_events, [:user_id]
    add_index :ahoy_events, [:time]
  end
end

Creates a schema like this:

  create_table "ahoy_events", force: true do |t|
    t.uuid     "visit_id",   limit: 16
    t.integer  "user_id"
    t.string   "name"
    t.text     "properties"
    t.datetime "time"
  end

  add_index "ahoy_events", ["id"], name: "sqlite_autoindex_ahoy_events_1", unique: true
  add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time"
  add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id"
  add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id"

Which causes an error like this on schema loading (e.g. when running tests):

gems/sqlite3-1.3.8/lib/sqlite3/database.rb:91:in `initialize': SQLite3::SQLException: object name reserved for internal use: sqlite_autoindex_ahoy_events_1: CREATE UNIQUE INDEX "sqlite_autoindex_ahoy_events_1" ON "ahoy_events" ("id") (ActiveRecord::StatementInvalid)

I've been unsuccessful in figuring out where that sqlite_autoindex line comes from, but changing t.uuid to t.binary seems to prevent it from happening. Is this a valid fix for sqlite? On the other hand, I'd very much like a migration that works both on our PostgreSQL servers and local development SQLites.

pyromaniac commented 9 years ago

Yeah, It was quite difficult to patch schema dumper, so it was never done. The solution - use sql schema.

luopio commented 9 years ago

Thanks. This works for me now

  create_table :ahoy_events, id: false do |t|
    t.binary :id, primary_key: true, limit: 16
    t.binary :visit_id, limit: 16
    [...]
luopio commented 9 years ago

... and adding self.primary_key = :id in the models.