Skip to content

Commit 62aa3a3

Browse files
committed
warn instead of raise on schema mismatch
1 parent 1f09463 commit 62aa3a3

4 files changed

Lines changed: 54 additions & 22 deletions

File tree

pyrit/memory/azure_sql_memory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ def __init__(
120120
if not skip_schema_migration:
121121
if self._connection_string == prod_connection_string:
122122
# Production guard: verify schema compatibility without modifying the database.
123-
# This allows normal usage when schemas match, but raises early if there's a mismatch.
123+
# Logs a warning on mismatch but does not block startup, so developers on
124+
# newer code can still query prod data.
124125
self._check_schema_migration(silent=silent)
125126
else:
126127
# For non-production databases, run normal schema migration which will create/update tables as needed.

pyrit/memory/memory_interface.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,19 +1438,30 @@ def _check_schema_migration(self, *, silent: bool = False) -> None:
14381438
"""
14391439
Verify that the current database schema matches the models without modifying the database.
14401440
1441+
Logs a warning if the schema does not match, but does not raise or block startup.
1442+
14411443
Args:
14421444
silent (bool): If True, suppresses Alembic console output. Defaults to False.
14431445
14441446
Raises:
14451447
RuntimeError: If the engine is not initialized.
1446-
AutogenerateDiffsDetected: If the schema does not match the models.
14471448
"""
1449+
from alembic.util.exc import AutogenerateDiffsDetected
1450+
14481451
from pyrit.memory.migration import check_schema_migrations
14491452

14501453
logger.info("Checking schema migration compatibility.")
14511454
if self.engine is None:
14521455
raise RuntimeError("Engine must be initialized to check schema migrations.")
1453-
check_schema_migrations(engine=self.engine, silent=silent)
1456+
try:
1457+
check_schema_migrations(engine=self.engine, silent=silent)
1458+
except AutogenerateDiffsDetected:
1459+
logger.warning(
1460+
"Schema mismatch detected on production database. "
1461+
"Your code models differ from the database schema. "
1462+
"This may cause errors if your code references columns or tables that don't exist. "
1463+
"Schema was NOT modified."
1464+
)
14541465

14551466
def reset_database(self) -> None:
14561467
"""

tests/unit/memory/test_azure_sql_memory.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -653,10 +653,8 @@ def test_init_prod_connection_runs_check_only_not_migration():
653653
Singleton._instances.update(saved)
654654

655655

656-
def test_init_prod_connection_raises_when_schema_mismatches():
657-
"""When connection matches prod and schema doesn't match models, the check raises."""
658-
from alembic.util.exc import AutogenerateDiffsDetected
659-
656+
def test_init_prod_connection_warns_on_schema_mismatch():
657+
"""When connection matches prod and schema doesn't match, startup succeeds with a warning (no raise)."""
660658
prod_conn = "Server=tcp:prod.database.windows.net;Database=prod_db;"
661659
saved = Singleton._instances.copy()
662660
Singleton._instances.clear()
@@ -665,15 +663,7 @@ def test_init_prod_connection_raises_when_schema_mismatches():
665663
patch("pyrit.memory.AzureSQLMemory._create_engine"),
666664
patch("pyrit.memory.AzureSQLMemory._create_auth_token"),
667665
patch("pyrit.memory.AzureSQLMemory._enable_azure_authorization"),
668-
patch.object(
669-
AzureSQLMemory,
670-
"_check_schema_migration",
671-
side_effect=AutogenerateDiffsDetected(
672-
"New upgrade operations detected",
673-
revision_context=MagicMock(),
674-
diffs=[],
675-
),
676-
),
666+
patch.object(AzureSQLMemory, "_check_schema_migration") as mock_check,
677667
patch.dict(
678668
"os.environ",
679669
{
@@ -683,12 +673,13 @@ def test_init_prod_connection_raises_when_schema_mismatches():
683673
},
684674
),
685675
):
686-
with pytest.raises(AutogenerateDiffsDetected):
687-
AzureSQLMemory(
688-
connection_string=prod_conn,
689-
results_container_url="https://test.blob.core.windows.net/test",
690-
results_sas_token="valid_sas_token",
691-
)
676+
# Should not raise — _check_schema_migration warns internally on mismatch
677+
AzureSQLMemory(
678+
connection_string=prod_conn,
679+
results_container_url="https://test.blob.core.windows.net/test",
680+
results_sas_token="valid_sas_token",
681+
)
682+
mock_check.assert_called_once()
692683
finally:
693684
Singleton._instances.clear()
694685
Singleton._instances.update(saved)

tests/unit/memory/test_migration.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,35 @@ def test_memory_interface_check_schema_migration_calls_check():
618618
mock_check.assert_called_once_with(engine=obj.engine, silent=True)
619619

620620

621+
def test_memory_interface_check_schema_migration_warns_on_mismatch(caplog):
622+
"""_check_schema_migration logs a warning instead of raising when schema mismatches."""
623+
import logging
624+
from unittest.mock import MagicMock, patch
625+
626+
from alembic.util.exc import AutogenerateDiffsDetected
627+
628+
from pyrit.memory.memory_interface import MemoryInterface
629+
630+
obj = MagicMock(spec=MemoryInterface)
631+
obj.engine = MagicMock()
632+
633+
with (
634+
patch(
635+
"pyrit.memory.migration.check_schema_migrations",
636+
side_effect=AutogenerateDiffsDetected(
637+
"diffs detected",
638+
revision_context=MagicMock(),
639+
diffs=[],
640+
),
641+
),
642+
caplog.at_level(logging.WARNING),
643+
):
644+
# Should NOT raise
645+
MemoryInterface._check_schema_migration(obj, silent=True)
646+
647+
assert "Schema mismatch detected on production database" in caplog.text
648+
649+
621650
def test_memory_interface_check_schema_migration_raises_without_engine():
622651
"""_check_schema_migration raises RuntimeError when engine is None."""
623652
from unittest.mock import MagicMock

0 commit comments

Comments
 (0)