Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8829701
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T07:53:41+00:00 2026-06-14T07:53:41+00:00

I would like to insert a record into a table and if the record

  • 0

I would like to insert a record into a table and if the record is already present get its id, otherwise run the insert and get the new record’s id.

I will be inserting millions of records and have no idea how to do this in an efficient manner. What I am doing now is to run a select to check if the record is already present, and if not, insert it and get the inserted record’s id. As the table is growing I imagine that SELECT is going to kill me.

What I am doing now in python with psycopg2 looks like this:

select = ("SELECT id FROM ... WHERE ...", [...])
cur.execute(*select)
if not cur.rowcount:
    insert = ("INSERT INTO ... VALUES ... RETURNING id", [...])
    cur.execute(*insert)
rid = cur.fetchone()[0]

Is it maybe possible to do something in a stored procedure like this:

BEGIN
    EXECUTE sql_insert;
    RETURN id;
    EXCEPTION WHEN unique_violation THEN
        -- return id of already existing record
        -- from the exception info ?
END;

Any ideas of how optimize a case like this?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T07:53:42+00:00Added an answer on June 14, 2026 at 7:53 am

    First off, this is obviously not an UPSERT as UPDATE was never mentioned. Similar concurrency issues apply, though.

    There will always be a race condition for this kind of task, but you can minimize it to an extremely tiny time slot, while at the same time querying for the ID only once with a data-modifying CTE (introduced with PostgreSQL 9.1):

    Given a table tbl:

    CREATE TABLE tbl(tbl_id serial PRIMARY KEY, some_col text UNIQUE);
    

    Use this query:

    WITH x AS (SELECT 'baz'::text AS some_col) -- enter value(s) once
    
       , y AS (
       SELECT x.some_col
            , (SELECT t.tbl_id FROM tbl t WHERE t.some_col = x.some_col) AS tbl_id
       FROM   x    
       )
    
       , z AS (
       INSERT INTO tbl(some_col)
       SELECT y.some_col
       FROM   y
       WHERE  y.tbl_id IS NULL
       RETURNING tbl_id
    )
    
    SELECT COALESCE(
             (SELECT tbl_id FROM z)
            ,(SELECT tbl_id FROM y)
           );
    
    • CTE x is only for convenience: enter values once.
    • CTE y retrieves tbl_id – if it already exists.
    • CTE z inserts the new row – if it doesn’t.
    • The final SELECT avoids running another query on the table with the COALESCE construct.

    Now, this can still fail if a concurrent transaction commits a new row with some_col = ‘foo’ exactly between CTE y and z, but that’s extremely unlikely. If it happens you get a duplicate key violation and have to retry. Nothing lost. If you don’t face concurrent writes, you can just forget about this.

    You can put this into a plpgsql function and rerun the query on duplicate key error automatically.

    Goes without saying that you need two indexes in this setup (like displayed in my CREATE TABLE statement above):

    • a UNIQUE or PRIMARY KEY constraint on tbl_id (which is of serial type!)
    • another UNIQUE or PRIMARY KEY constraint on some_col

    Both implement an index automatically.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I would like to insert a new DataGridViewRow into my DataGridView at a specific
i am inserting values into a table if the record exists already replace it,
When inserting a new row in a table T, I would like to check
I would like to know more about inserting into one table a value right
I would like to insert the output of multiple calculations into my text document:
I have created a test table in MySQL and would like to insert 10
I want to create a new table and then insert a specific record in
I would like to archive a student by moving the record from one table
I would like to insert an array into a MYSQL database, preferably using Yii's
I'm inserting a record into a table where Id is of type uniqueidenfier .

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.