Skip to content

Commit 5158518

Browse files
committed
fix(migrations): clarify sequence widening handling in PostgreSQL bigint migration
- Added comments to explain that altering column types does not change SERIAL sequence types. - Noted that sequence widening is managed by a previous migration.
1 parent 77c2156 commit 5158518

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

app/db/migrations/versions/4f15c0789493_use_bigint_for_id_column.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ def _upgrade_mysql() -> None:
8888
def _upgrade_postgresql() -> None:
8989
"""PostgreSQL: Direct column alteration (automatically cascades to FKs)"""
9090
_alter_columns_to_bigint()
91+
# ALTER COLUMN ... TYPE BIGINT does not change SERIAL sequence types.
92+
# Sequence widening is handled by 8e2f1a9c4b70.
9193

9294

9395
def _is_bigint_type(sqlalchemy_type) -> bool:
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"""widen leftover PostgreSQL INTEGER sequences to BIGINT
2+
3+
Revision ID: 8e2f1a9c4b70
4+
Revises: 7c4bd5128e62
5+
Create Date: 2026-09-08 11:30:00.000000
6+
7+
ALTER COLUMN ... TYPE BIGINT does not change SERIAL/IDENTITY sequence types.
8+
PostgreSQL INSERT ... ON CONFLICT still calls nextval(), so high-churn tables
9+
like node_user_usages exhaust INTEGER sequences at 2147483647.
10+
"""
11+
12+
from alembic import op
13+
import sqlalchemy as sa
14+
15+
16+
revision = "8e2f1a9c4b70"
17+
down_revision = "7c4bd5128e62"
18+
branch_labels = None
19+
depends_on = None
20+
21+
22+
def upgrade() -> None:
23+
bind = op.get_bind()
24+
if bind.dialect.name != "postgresql":
25+
return
26+
27+
# Idempotent: only sequences still typed as integer are touched.
28+
# Columns already BIGINT skip the table rewrite; only the sequence type changes.
29+
op.execute(
30+
sa.text(
31+
"""
32+
DO $$
33+
DECLARE
34+
rec RECORD;
35+
BEGIN
36+
FOR rec IN
37+
SELECT
38+
n.nspname AS schema_name,
39+
s.relname AS sequence_name,
40+
t.relname AS table_name,
41+
a.attname AS column_name,
42+
format_type(a.atttypid, a.atttypmod) AS column_type
43+
FROM pg_class s
44+
JOIN pg_namespace n ON n.oid = s.relnamespace
45+
JOIN pg_depend d ON d.objid = s.oid AND d.deptype IN ('a', 'i')
46+
JOIN pg_class t ON t.oid = d.refobjid
47+
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid
48+
JOIN pg_sequence seq ON seq.seqrelid = s.oid
49+
WHERE s.relkind = 'S'
50+
AND n.nspname = current_schema()
51+
AND seq.seqtypid = 'integer'::regtype
52+
AND a.attnum > 0
53+
AND NOT a.attisdropped
54+
LOOP
55+
IF rec.column_type NOT IN ('bigint', 'int8') THEN
56+
EXECUTE format(
57+
'ALTER TABLE %I.%I ALTER COLUMN %I TYPE BIGINT',
58+
rec.schema_name,
59+
rec.table_name,
60+
rec.column_name
61+
);
62+
END IF;
63+
64+
EXECUTE format(
65+
'ALTER SEQUENCE %I.%I AS bigint',
66+
rec.schema_name,
67+
rec.sequence_name
68+
);
69+
END LOOP;
70+
END
71+
$$;
72+
"""
73+
)
74+
)
75+
76+
77+
def downgrade() -> None:
78+
# Values may already exceed INTEGER range; shrinking sequences is unsafe.
79+
pass

0 commit comments

Comments
 (0)