@@ -55,14 +55,35 @@ def migrate_schema(self, template_schema: str, target_schema: str) -> None:
5555 self ._set_replica_identity (target_schema )
5656
5757 def _ensure_box_columns (self , schema : str ) -> None :
58- """Add columns that may be missing from older template snapshots."""
58+ """Add columns that may be missing from older template snapshots.
59+
60+ Only runs against schemas that actually contain Box tables. Each
61+ ALTER TABLE is wrapped in a SAVEPOINT so that a single failure does
62+ not poison the surrounding transaction (the same pattern used by
63+ ``_copy_custom_indexes``).
64+ """
5965 _columns = [
6066 # (table, column, SQL type, default)
6167 ("box_folders" , "path" , "VARCHAR(500)" , "'/'" ),
6268 ("box_files" , "path" , "VARCHAR(500)" , "'/0/'" ),
6369 ]
6470 with self .session_manager .base_engine .begin () as conn :
71+ # Quick check: skip entirely when the schema has no Box tables.
72+ has_box = conn .execute (
73+ text (
74+ "SELECT EXISTS("
75+ " SELECT 1 FROM information_schema.tables"
76+ " WHERE table_schema = :schema"
77+ " AND table_name = 'box_folders'"
78+ ")"
79+ ),
80+ {"schema" : schema },
81+ ).scalar ()
82+ if not has_box :
83+ return
84+
6585 for table , col , sql_type , default in _columns :
86+ nested = conn .begin_nested ()
6687 try :
6788 conn .execute (
6889 text (
@@ -71,7 +92,9 @@ def _ensure_box_columns(self, schema: str) -> None:
7192 f"DEFAULT { default } "
7293 )
7394 )
95+ nested .commit ()
7496 except Exception as exc :
97+ nested .rollback ()
7598 logger .warning (
7699 f"Could not ensure column { schema } .{ table } .{ col } : { exc } "
77100 )
0 commit comments