Multiple inserts via pgsql function cause error

Viewed 25

I have a pgsql function which looks up a value (unique constraint) in a table and returns the id. If the value does not exist, it creates the entry and returns the id. The id is used to create rows in another table. I use the function with node-pg to bulk-insert. Most of the time, it works good, but sometimes returns

ERROR duplicate key value violates unique constraint "collections_slug_key" Key (slug)=(heroes-follow-heroes) already exists.","where":"SQL statement "INSERT INTO collections (slug)\n\t\t\tVALUES (slug_) RETURNING id"\nPL/pgSQL function myfunction(slug, key) line 11

I don't understand it, since I also tried it in a transaction (and I thought pgsql functions are in a transaction anyway).

The sql to create the table looks like this:

BEGIN TRANSACTION;

CREATE TABLE collections (
    id BIGSERIAL PRIMARY KEY,
    slug TEXT NOT NULL,
    UNIQUE(slug)
);

CREATE OR REPLACE FUNCTION myFunction(
    slug_ TEXT,
    key_ TEXT)
RETURNS VOID AS $$
BEGIN
    DECLARE
        collection_id_ BIGINT;

    BEGIN
        SELECT INTO collection_id_ id
        FROM collections AS c
        WHERE c.slug = slug_;
        IF NOT FOUND THEN
            INSERT INTO collections (slug)
            VALUES (slug_) RETURNING id INTO collection_id_;
        END IF;
    END;
END;
$$
LANGUAGE plpgsql;

COMMIT;

The insert-code looks like this:

SELECT myFunction(
    b.slug,
    b.key)
FROM json_to_recordset($1)
AS b(
    slug TEXT,
    key TEXT
)

I used a basic node-pg query:

await client.query({
    "name": "INSERT_MY",
    "text": await FILE_CONTENT_QUERY,
    "values": [JSON.stringify(data)],
});

I also tried node-pg transactions with manual BEGIN, COMMIT, ROLLBACK, but it had the same issues. Any ideas?

0 Answers
Related