fix: scope reliability migration indexes

This commit is contained in:
2026-08-04 11:25:47 +08:00
parent fee707f42d
commit e12cda3906
2 changed files with 49 additions and 4 deletions
@@ -105,7 +105,11 @@ def _create_missing_indexes(connection: Connection) -> None:
existing_indexes = { existing_indexes = {
index["name"] for index in inspector.get_indexes(table.name) index["name"] for index in inspector.get_indexes(table.name)
} }
for index in table.indexes: index = next(
item
for item in table.indexes
if item.name == "idx_ping_records_device_created_at"
)
if index.name not in existing_indexes: if index.name not in existing_indexes:
index.create(bind=connection) index.create(bind=connection)
+42 -1
View File
@@ -4,7 +4,7 @@ import importlib
from pathlib import Path from pathlib import Path
import pytest import pytest
from sqlalchemy import Column, Integer, Table, inspect, text from sqlalchemy import Column, Index, Integer, Table, inspect, text
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
import app.models as models import app.models as models
@@ -249,3 +249,44 @@ async def test_migration_preserves_legacy_rows_and_owns_only_its_schema(
if future_table in Base.metadata.tables.values(): if future_table in Base.metadata.tables.values():
Base.metadata.remove(future_table) Base.metadata.remove(future_table)
await engine.dispose() await engine.dispose()
async def test_migration_does_not_create_a_future_ping_record_index(
tmp_path: Path,
):
"""Historical migration DDL stays limited to its named composite index."""
migration = importlib.import_module(
"migrations.versions.20260803_reliability_monitoring"
)
future_index = Index(
"idx_future_ping_record_round_num",
models.PingRecord.__table__.c.round_num,
)
engine = create_async_engine(
f"sqlite+aiosqlite:///{tmp_path / 'future-index.db'}"
)
try:
async with engine.begin() as connection:
await connection.execute(
text(
"CREATE TABLE ping_records ("
"id INTEGER PRIMARY KEY, device_id INTEGER NOT NULL, "
"is_alive BOOLEAN NOT NULL, response_time_ms FLOAT, "
"round_num INTEGER NOT NULL, created_at DATETIME)"
)
)
await connection.run_sync(migration.run_reliability_migration)
index_names = await connection.run_sync(
lambda sync_connection: {
index["name"]
for index in inspect(sync_connection).get_indexes(
"ping_records"
)
}
)
assert "idx_ping_records_device_created_at" in index_names
assert "idx_future_ping_record_round_num" not in index_names
finally:
models.PingRecord.__table__.indexes.remove(future_index)
await engine.dispose()