Skip to content

Commit 835e166

Browse files
committed
db/export: reset PostgreSQL sequences after data import
Inserting rows with explicit IDs does not advance PostgreSQL sequences. The next auto-generated ID collides with existing rows. Emit a PL/pgSQL block that discovers all serial columns and resets their sequences to max(id) + 1. Signed-off-by: Robin Jarry <robin@jarry.cc>
1 parent c9b6c67 commit 835e166

1 file changed

Lines changed: 26 additions & 0 deletions

File tree

pkg/db/export.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func Export(ctx context.Context, database *bun.DB, w io.Writer, target string) e
131131
}
132132
}
133133

134+
writeResetSequences(w, d)
134135
writeEnableConstraints(w, d)
135136
fmt.Fprint(w, "COMMIT;\n")
136137
return nil
@@ -154,6 +155,31 @@ func writeEnableConstraints(w io.Writer, d schema.Dialect) {
154155
}
155156
}
156157

158+
func writeResetSequences(w io.Writer, d schema.Dialect) {
159+
if d.Name() != dialect.PG {
160+
return
161+
}
162+
io.WriteString(w, `DO $$
163+
DECLARE
164+
r RECORD;
165+
BEGIN
166+
FOR r IN
167+
SELECT c.oid::regclass::text AS tbl,
168+
a.attname AS col
169+
FROM pg_catalog.pg_class c
170+
JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
171+
WHERE c.relkind = 'r'
172+
AND pg_get_serial_sequence(c.oid::regclass::text, a.attname) IS NOT NULL
173+
LOOP
174+
EXECUTE format(
175+
'SELECT setval(pg_get_serial_sequence(%L, %L), coalesce(max(%I), 0) + 1, false) FROM %s',
176+
r.tbl, r.col, r.col, r.tbl);
177+
END LOOP;
178+
END
179+
$$;
180+
`)
181+
}
182+
157183
func hasDjangoMigrations(ctx context.Context, database *bun.DB) bool {
158184
_, err := database.NewSelect().
159185
TableExpr("django_migrations").

0 commit comments

Comments
 (0)