PostgreSQL Bulk INSERT with ON CONFLICT

Generate PostgreSQL-compatible bulk INSERT statements with double-quoted identifiers and ON CONFLICT DO UPDATE SET syntax for upserts.

Dialect Differences

Detailed Explanation

PostgreSQL-Specific Bulk INSERT

PostgreSQL offers the most flexible INSERT syntax among major databases. The bulk INSERT tool generates idiomatic PostgreSQL output with proper quoting and conflict handling.

PostgreSQL Identifier Quoting

PostgreSQL uses double quotes for identifiers:

INSERT INTO "users" ("id", "first_name", "email")
VALUES
  (1, 'Alice', 'alice@example.com'),
  (2, 'Bob', 'bob@example.com');

ON CONFLICT Syntax

PostgreSQL's upsert uses the ON CONFLICT clause:

DO NOTHING (skip duplicates):

INSERT INTO "users" ("id", "name", "email")
VALUES
  (1, 'Alice', 'alice@example.com')
ON CONFLICT ("id") DO NOTHING;

DO UPDATE SET (upsert):

INSERT INTO "users" ("id", "name", "email")
VALUES
  (1, 'Alice Updated', 'alice.new@example.com')
ON CONFLICT ("id") DO UPDATE SET
  "name" = EXCLUDED."name",
  "email" = EXCLUDED."email";

The EXCLUDED pseudo-table references the row that would have been inserted, making it easy to reference new values in the UPDATE clause.

PostgreSQL Strengths for Bulk Inserts

  • No practical row limit per INSERT statement
  • JSONB support: Nested objects can be stored in JSONB columns
  • COPY command: For ultimate speed, export as CSV and use COPY
  • Parallel execution: Multiple batches can run in parallel transactions

Performance Tips

For PostgreSQL, batch sizes of 500-1000 are typically optimal. The database handles large statements efficiently, so you can use larger batches than MySQL or SQLite.

Use Case

You are loading JSON data from an external API into PostgreSQL, and the API may return duplicate records. Using ON CONFLICT DO UPDATE ensures your data stays current without manual deduplication.

Try It — JSON to Bulk INSERT

Open full tool