Search code examples
postgresqlactiverecordherokuruby-on-rails-3.2cedar

Duplicate primary key, can't access psql console


Problem creating new records in postgres database. Using Heroku Cedar stack and Rails 3.2.

Calling create results in

ActiveRecord::RecordNotUnique (PG::Error: ERROR:  duplicate key value violates unique constraint "answer_selections_pkey"

Here's my schema for the problem table (it should be using the implicit auto-increment id column):

  create_table "answer_selections", :force => true do |t|                                                              
    t.integer "individual_id"
    t.integer "answer_choice_id"
    t.boolean "still_true",       :default => false
  end

And here's the error when calling create.

2012-09-07T14:46:44+00:00 app[web.1]: ActiveRecord::RecordNotUnique (PG::Error: ERROR:  duplicate key value violates unique constraint "answer_selections_pkey"
2012-09-07T14:46:44+00:00 app[web.1]: : INSERT INTO "answer_selections" ("answer_choice_id", "individual_id", "still_true") VALUES ($1, $2, $3) RETURNING "id"):
2012-09-07T14:46:44+00:00 app[web.1]:   app/controllers/answer_selections_controller.rb:10:in `create'

Similarly, I see the same error on another table:

2012-09-09T04:10:34+00:00 app[web.2]: ActiveRecord::RecordNotUnique (PG::Error: ERROR:  duplicate key value violates unique constraint "trips_pkey"
2012-09-09T04:10:34+00:00 app[web.2]: : INSERT INTO "trips" ("booked", "created_at", "destination_id", "end_date", "individual_id", "n_travelers", "name", "start_date", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING "id"):

Unable to access postgres database directly, as the connection times out:

$ heroku pg:psql
psql: could not connect to server: Connection timed out

How can I repair this, and how can I avoid it in the future? I have read that running VACCUUM and ANALYZE will solve it, but as I said I cannot access psql.

Edit to add requested info (sample schema included above, we're using ActiveRecord):

@record.create(params) # How these records are created

Solution

  • I'm not sure what happened to your data but somehow the sequence that supplies id values has gotten out of sync with the table's id values; this can happen if you supply an explicit id value in an INSERT like this:

    insert into t (id, col) values (11, 'pancakes')
    

    Perhaps you've loaded some bulk data but didn't kick your sequences back into sense.

    In any case, a simple migration can sort you out:

    class KickAnswerSelectionSequence < ActiveRecord::Migration
        def up
            connection.execute(%q{
                select setval('answer_selections_id_seq', max(id))
                from answer_selections
            })
        end
        def down
            raise ActiveRecord::IrreversibleMigration
        end
    end
    

    You'll want to repeat that for all the tables that are giving you problems, might be a good idea to do it for all your tables just to be safe.

    You can read more on sequence manipulation functions if desired:

    http://www.postgresql.org/docs/current/interactive/functions-sequence.html

    As to your problem with heroku pg:psql, you'll have to talk to Heroku about that.