Inserting Data in Postgres
This post is more of a reference of all the ways to insert data into a Postgres database.
Let’s start out with an NBA schema.
Insert with Values
Using default values can be helpful.
id |
---|
1 |
Insert Select
If you’re inserting a lot of data, this is a good way to go.
Upserting, or Handling Conflicts
Let’s say we want to insert a row, but only if there’s not a conflict.
What if we want to
- insert the row if it doesn’t exist
- do nothing if it does
- but return the row regardless
id | city | name |
---|---|---|
3 | Brooklyn | Nets |
Or, we may want to actually update the existing row. This is the “upsert” pattern.
id | city | name |
---|---|---|
3 | New Jersey | Nets |
Note that there needs to be a unique constraint on whatever is in the on conflict
clause. If not, you will get ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
.
Furthermore, we can call out the constraint by name. To demonstrate, let’s add a number
column to the players
table and make it unique per team.
Now, let’s try to violate it.
Sweet, we get ERROR: duplicate key value violates unique constraint "players_number_unique"
.
id | team_id | name | height | number |
---|---|---|---|---|
9 | 14 | LeBron James | 0 |
That is cool, but it is usually better just to specify the column names directly.
Upserting via a Merge Statement
There’s another way to do insert on conflict
- the merge
statement.
You can do a bit more with merge
than you can with insert on conflict
.
- With a
merge
statement, you can have multiple matching conditions, whileinsert on conflict
only allows one. - With a
merge
statement, you can have complex conditions in the matching clause, rather than only being able to match on a unique constraint. - With a
merge
statement, you can delete a row on a match.
Insert in a CTE
To set this example up, let’s change our schema a bit.
Now, we can do an insert statement in a CTE:
id | city | name | formerly |
---|---|---|---|
21 | Oklahoma City | Thunder | 34 |
Copying Data From a File
Let me start with a clean slate for this:
Now, I can copy the data in, using the copy
command.
id | city | name | formerly |
---|---|---|---|
1 | Boston | Celtics | |
2 | Los Angeles | Lakers | |
3 | Chicago | Bulls | |
4 | Atlanta | Hawks | |
5 | San Antonio | Spurs | |
6 | Miami | Heat | |
7 | Houston | Rockets | |
8 | New York | Knicks | |
9 | Syracuse | Nationals | |
10 | Detroit | Pistons | |
11 | Philadelphia | 76ers | 9 |
You can even insert data from a program in this way:
Wow! You read the whole thing. People who make it this far sometimes
want to receive emails when I post something new.
I also have an RSS feed.