Skip to content

Commit

Permalink
Revert "Remove note re: ON CONFLICT ON CONSTRAINT (github#1522)" (g…
Browse files Browse the repository at this point in the history
…ithub#1532)

This reverts commit 7e49315.
  • Loading branch information
charislam authored Sep 1, 2022
1 parent 7e49315 commit f440aa0
Showing 1 changed file with 21 additions and 10 deletions.
31 changes: 21 additions & 10 deletions timescaledb/how-to-guides/write-data/upsert.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ keywords: [upsert, hypertables]
---

# Upsert data

Upserting is shorthand for:

* Inserting a new row if a matching row doesn't already exist
* Either updating the existing row, or doing nothing, if a matching row
already exists
Expand All @@ -22,11 +20,9 @@ If you have a primary key, you automatically have a unique index.
</highlight>

## Create a table with a unique constraint

The examples in this section use a `conditions` table with a unique constraint
on the columns `(time, location)`. To create a unique constraint, use `UNIQUE
(<COLUMNS>)` while defining your table:

```sql
CREATE TABLE conditions (
time TIMESTAMPTZ NOT NULL,
Expand All @@ -40,7 +36,6 @@ CREATE TABLE conditions (
You can also create a unique constraint after the table is created. Use the
syntax `ALTER TABLE ... ADD CONSTRAINT ... UNIQUE`. In this example, the
constraint is named `conditions_time_location`:

```sql
ALTER TABLE conditions
ADD CONSTRAINT conditions_time_location
Expand All @@ -61,14 +56,12 @@ well. For more information, see the section on
</highlight>

## Insert or update data to a table with a unique constraint

You can tell the database to insert new data if it doesn't violate the
constraint, and to update the existing row if it does. Use the syntax `INSERT
INTO ... VALUES ... ON CONFLICT ... DO UPDATE`.

For example, to update the `temperature` and `humidity` values if a row with the
specified `time` and `location` already exists, run:

specified `time` and `location` already exists, run:
```sql
INSERT INTO conditions
VALUES ('2017-07-28 11:42:42.846621+00', 'office', 70.2, 50.1)
Expand All @@ -78,19 +71,37 @@ INSERT INTO conditions
```

## Insert or do nothing to a table with a unique constraint

You can also tell the database to do nothing if the constraint is violated. The
new data is not inserted, and the old row is not updated. This is useful when
writing many rows as one batch, to prevent the entire transaction from failing.
The database engine skips the row and moves on.

To insert or do nothing, use the syntax `INSERT INTO ... VALUES ... ON CONFLICT
DO NOTHING`:

```sql
INSERT INTO conditions
VALUES ('2017-07-28 11:42:42.846621+00', 'office', 70.1, 50.0)
ON CONFLICT DO NOTHING;
```

<highlight type="note">
You cannot specify a constraint by name when using `INSERT ... ON CONFLICT` on
hypertables. Work around this by explicitly specifying the constrained columns.
For example, instead of this:

```sql
-- This does not work
INSERT INTO conditions
VALUES ('2017-07-28 11:42:42.846621+00', 'office', 70.1, 50.0)
ON CONFLICT ON CONSTRAINT conditions_time_location DO NOTHING;
```

Do this:
```sql
INSERT INTO conditions
VALUES ('2017-07-28 11:42:42.846621+00', 'office', 70.1, 50.0)
ON CONFLICT (time, location) DO NOTHING;
```
</highlight>

[postgres-upsert]: https://www.postgresql.org/docs/current/static/sql-insert.html#SQL-ON-CONFLICT

0 comments on commit f440aa0

Please sign in to comment.