Rails: does ActiveRecord :: RecordNotUnique repeat when creating objects using Postgres?

I am working with a Rails 4 application that needs to create a large number of objects in response to events from another system. I very often encounter errors ActiveRecord::RecordNotUnique(caused PG::UniqueViolation) in the primary key column when I call create!on one of my models.

I found other answers on SO that involve saving the exception and calling retry:

begin
  TableName.create!(data: 'here')
rescue ActiveRecord::RecordNotUnique => e
  if e.message.include? '_pkey' # Only retry primary key violations
    log.warn "Retrying creation: #{e}"
    retry
  else
    raise
  end
end

Although this seems to help, I still get tons of errors ActiveRecord::RecordNotUniquefor sequential identifiers that already exist in the database (shortened log entries):

WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3067) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3068) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3069) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3070) already exists.

The identifiers that he is trying to use are in the range of 3000-4000, even if more than 90,000 entries are indicated in the table.

ActiveRecord PostgreSQL ?


(/ ):

{
  "exception": "ActiveRecord::RecordNotUnique",
  "message": "PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint \"table_name_pkey\"\nDETAIL:  Key (id)=(3023) already exists."
}
+4
2

, , , PostgreSQL - reset :

SELECT nextval('table_name_id_seq');
-- 3456

SELECT max(id) FROM table_name;
-- 95123

:

ALTER SEQUENCE table_name_id_seq RESTART 95124;

: Rake reset ID Rails 4 PostgreSQL:

desc 'Resets Postgres auto-increment ID column sequences to fix duplicate ID errors'
task :reset_sequences => :environment do
  Rails.application.eager_load!

  ActiveRecord::Base.descendants.each do |model|
    unless model.attribute_names.include?('id')
      Rails.logger.debug "Not resetting #{model}, which lacks an ID column"
      next
    end

    begin
      max_id = model.maximum(:id).to_i + 1
      result = ActiveRecord::Base.connection.execute(
        "ALTER SEQUENCE #{model.table_name}_id_seq RESTART #{max_id};"
      )
      Rails.logger.info "Reset #{model} sequence to #{max_id}"
    rescue => e
      Rails.logger.error "Error resetting #{model} sequence: #{e.class.name}/#{e.message}"
    end
  end
end

:

+16

reset 'table_name', rails

> ActiveRecord::Base.connection.reset_pk_sequence!('table_name')

( 3.2)

+4

All Articles