Skip to content

Commit 0f060e2

Browse files
authored
db-dump: Reset sequences after data import (#11506)
This automatically resets all `id` column sequences to the maximum `id` column value of the corresponding table after the data was imported.
1 parent 0e32084 commit 0f060e2

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

script/import-database-dump.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,16 @@ psql -a "$DATABASE_NAME" < schema.sql
5858
echo "Importing data"
5959
psql -a "$DATABASE_NAME" < import.sql
6060

61+
cd "$ORIG_WD"
62+
6163
# Importing the database doesn't cause materialised views to be refreshed, so
6264
# let's do that.
6365
psql --command="REFRESH MATERIALIZED VIEW recent_crate_downloads" "$DATABASE_NAME"
6466

67+
# Reset all ID sequence values to match the imported data
68+
echo "Resetting sequence values"
69+
psql -a "$DATABASE_NAME" < "$(dirname "$0")/reset-sequences.sql"
70+
6571
# Importing the database also doesn't insert Diesel migration metadata, but we
6672
# can infer that from the dump metadata and an up to date crates.io repo.
67-
cd "$ORIG_WD"
6873
python3 "$(dirname "$0")/infer-database-dump-version.py" -m "$DUMP_PATH/metadata.json" | psql -a "$DATABASE_NAME"

script/reset-sequences.sql

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
-- Reset all ID column sequences to their maximum values or 1
2+
-- This script dynamically discovers all sequences associated with 'id' columns
3+
-- and sets them to either the maximum id value in the table or 1 if empty
4+
5+
DO $$
6+
DECLARE
7+
rec RECORD;
8+
max_id BIGINT;
9+
BEGIN
10+
FOR rec IN
11+
WITH id_sequences AS (
12+
SELECT
13+
pg_class.relname AS sequence_name,
14+
pg_class_tables.relname AS table_name
15+
FROM pg_class
16+
JOIN pg_depend ON pg_depend.objid = pg_class.oid
17+
JOIN pg_class pg_class_tables ON pg_depend.refobjid = pg_class_tables.oid
18+
JOIN pg_attribute ON pg_depend.refobjid = pg_attribute.attrelid AND pg_depend.refobjsubid = pg_attribute.attnum
19+
JOIN pg_namespace ON pg_class_tables.relnamespace = pg_namespace.oid
20+
WHERE pg_class.relkind = 'S' -- sequences
21+
AND pg_attribute.attname = 'id' -- only 'id' columns
22+
AND pg_namespace.nspname = 'public' -- only public schema
23+
)
24+
SELECT * FROM id_sequences
25+
LOOP
26+
-- Get the maximum id value from the table
27+
EXECUTE format('SELECT MAX(id) FROM public.%I', rec.table_name) INTO max_id;
28+
29+
-- Reset the sequence to the max value or 1 if empty
30+
--
31+
-- Use is_called = false for empty tables (max_id IS NULL),
32+
-- and is_called = true for populated tables
33+
PERFORM setval('public.' || rec.sequence_name, COALESCE(max_id, 1), max_id IS NOT NULL);
34+
35+
-- Log the action
36+
RAISE NOTICE 'Reset sequence % to % (table: %, is_called: %)', rec.sequence_name, COALESCE(max_id, 1), rec.table_name, max_id IS NOT NULL;
37+
END LOOP;
38+
END $$;

0 commit comments

Comments
 (0)