mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-16 13:20:39 -07:00
fix(db): graceful fallback when SQLite < 3.35 on MCP bindings migration
SQLite gained ALTER TABLE … DROP COLUMN in 3.35 (Mar 2021). Production PyInstaller builds bundle Python 3.12 which links to SQLite 3.40+ so that path is always safe, but a dev running the backend directly on Ubuntu 20.04 (3.31) or Debian 11 (3.34) would crash on first startup trying to drop the legacy default_intent column. Add _supports_drop_column(engine) — returns True on non-SQLite dialects (Postgres / MySQL have supported DROP COLUMN for decades) and gates on the runtime sqlite_version for SQLite. When unsupported, log a warning and leave the unused column in place: SQLAlchemy only maps declared columns, so a stray default_intent column does no reads or writes and can't interfere with runtime behaviour. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
0081e97ad7
commit
c0eba9c628
@@ -252,10 +252,37 @@ def _migrate_mcp_bindings(engine, inspector, tables: set[str]) -> None:
|
||||
"default_personality",
|
||||
)
|
||||
if "default_intent" in columns:
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text("ALTER TABLE mcp_client_bindings DROP COLUMN default_intent"))
|
||||
conn.commit()
|
||||
logger.info("Dropped legacy default_intent column from mcp_client_bindings")
|
||||
if _supports_drop_column(engine):
|
||||
with engine.connect() as conn:
|
||||
conn.execute(text("ALTER TABLE mcp_client_bindings DROP COLUMN default_intent"))
|
||||
conn.commit()
|
||||
logger.info("Dropped legacy default_intent column from mcp_client_bindings")
|
||||
else:
|
||||
# ALTER TABLE … DROP COLUMN on SQLite requires 3.35+ (Mar
|
||||
# 2021). Production PyInstaller builds bundle Python 3.12
|
||||
# which links to SQLite 3.40+; this branch only fires for
|
||||
# dev environments running the backend directly against an
|
||||
# old system SQLite (Ubuntu 20.04 = 3.31, Debian 11 = 3.34).
|
||||
# Leaving the unused column in place is harmless — the ORM
|
||||
# only maps declared columns, so a stray one does no work
|
||||
# and gets no reads or writes.
|
||||
import sqlite3
|
||||
|
||||
logger.warning(
|
||||
"SQLite %s too old to DROP COLUMN (need 3.35+); leaving unused default_intent column on mcp_client_bindings in place.",
|
||||
sqlite3.sqlite_version,
|
||||
)
|
||||
|
||||
|
||||
def _supports_drop_column(engine) -> bool:
|
||||
"""Whether ``ALTER TABLE … DROP COLUMN`` is supported by the dialect +
|
||||
runtime. Non-SQLite dialects (Postgres, MySQL) have supported it for
|
||||
decades; SQLite only gained the feature in 3.35."""
|
||||
if engine.dialect.name != "sqlite":
|
||||
return True
|
||||
import sqlite3
|
||||
|
||||
return tuple(int(p) for p in sqlite3.sqlite_version.split(".")[:3]) >= (3, 35, 0)
|
||||
|
||||
|
||||
def _normalize_storage_paths(engine, tables: set[str]) -> None:
|
||||
|
||||
Reference in New Issue
Block a user