Background: This is for a Ruby on Rails web application. I have a background job which downloads recent posts from Facebook and inserts them into the database. I’m using hand-coded SQL for performance. The RDBMS is PostgreSQL (on Heroku).
The table is called “posts”. I have a unique index on the combination of posts.uid and posts.contact_id. In the SQL, I use a WHERE condition to filter out uid–contact_id combinations which are already in the table, but even so, I am getting the following error:
ActiveRecord::RecordNotUnique: PGError: ERROR: duplicate key value violates unique constraint "index_posts_on_uid_and_contact_id"
Without further ado, here is the (dynamic) SQL:
INSERT INTO posts
(message,contact_id,date,uid,created_at,updated_at,source,is_event)
SELECT
t.msg,
contacts.id,
t.date,
t.uid,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP,'facebook',
FALSE
FROM contacts,
(VALUES #{posts.map { |post| "(E'#{post['message'].escape_singles}','#
{post['uid']}',DATE '#{format_date(post['time'])}',#{post['status_id']})" }.join(", ")}) AS
t (msg,fb_id,date,uid)
WHERE contacts.fb_id = t.fb_id
AND (NOT EXISTS (
SELECT * FROM posts
WHERE posts.uid = t.uid
AND posts.contact_id = contacts.id));
Shouldn’t the NOT EXISTS condition prevent this from happening?
Your select query is returning duplicate rows.