Postgres hasn't implemented an equivalent to INSERT OR REPLACE. From the ON CONFLICT docs (emphasis mine):
It can be either DO NOTHING, or a DO UPDATE clause specifying the exact details of the UPDATE action to be performed in case of a conflict.
Though it doesn't give you shorthand for replacement, ON CONFLICT DO UPDATE applies more generally, since it lets you set new values based on preexisting data. For example:
INSERT INTO users (id, level)
VALUES (1, 0)
ON CONFLICT (id) DO UPDATE
SET level = users.level + 1;
Answer from Kristján on Stack OverflowPostgres hasn't implemented an equivalent to INSERT OR REPLACE. From the ON CONFLICT docs (emphasis mine):
It can be either DO NOTHING, or a DO UPDATE clause specifying the exact details of the UPDATE action to be performed in case of a conflict.
Though it doesn't give you shorthand for replacement, ON CONFLICT DO UPDATE applies more generally, since it lets you set new values based on preexisting data. For example:
INSERT INTO users (id, level)
VALUES (1, 0)
ON CONFLICT (id) DO UPDATE
SET level = users.level + 1;
Unfortunately there isn't a shorter way to write that. You MUST specify each column you want to update in the do update section.
INSERT INTO tablename (id, username, password, level, email, update_count)
-- if id doesn't exist, do insert
VALUES (1, 'John', 'qwerty', 5, '[email protected]', 0)
-- how to check for duplicates (more versatile: could use any unique index here)
ON CONFLICT (id)
DO UPDATE
SET
-- update duplicate clause
username=EXCLUDED.username, -- references proposed insertion row
password=EXCLUDED.password,
level=EXCLUDED.level,
email=EXCLUDED.email,
update_count=tablename.update_count+1 -- reference existing row
on conflict will give you something similar to insert or replace from sqlite, but it's a more versatile function that is more focused on update rather than just a full row replace.