1616
1717import logging
1818
19+ from sqlalchemy import create_engine as create_sync_engine
1920from sqlalchemy import inspect
2021from sqlalchemy import text
2122
@@ -38,14 +39,16 @@ def _get_schema_version_impl(inspector, connection) -> str:
3839 if result :
3940 return result [0 ]
4041 else :
41- return LATEST_SCHEMA_VERSION
42+ raise ValueError (
43+ "Schema version not found in adk_internal_metadata. The database"
44+ " might be malformed."
45+ )
4246 except Exception as e :
43- logger .warning (
44- "Failed to query schema version from adk_internal_metadata,"
45- " assuming the latest schema: %s." ,
47+ logger .error (
48+ "Failed to query schema version from adk_internal_metadata: %s." ,
4649 e ,
4750 )
48- return LATEST_SCHEMA_VERSION
51+ raise
4952 # Metadata table doesn't exist, check for v0 schema.
5053 # V0 schema has an 'events' table with an 'actions' column.
5154 if inspector .has_table ("events" ):
@@ -57,17 +60,57 @@ def _get_schema_version_impl(inspector, connection) -> str:
5760 " serialize event actions. The v0 schema will not be supported"
5861 " going forward and will be deprecated in a few rollouts. Please"
5962 " migrate to the v1 schema which uses JSON serialization for event"
60- " data. The migration command and script will be provided soon."
63+ " data. You can use `adk migrate session` command to migrate your"
64+ " database."
6165 )
6266 return SCHEMA_VERSION_0_PICKLE
6367 except Exception as e :
64- logger .warning ("Failed to inspect 'events' table columns: %s" , e )
65- return LATEST_SCHEMA_VERSION
66- # New database, assume the latest schema.
68+ logger .error ("Failed to inspect 'events' table columns: %s" , e )
69+ raise
70+ # New database, use the latest schema.
6771 return LATEST_SCHEMA_VERSION
6872
6973
7074def get_db_schema_version_from_connection (connection ) -> str :
7175 """Gets DB schema version from a DB connection."""
7276 inspector = inspect (connection )
7377 return _get_schema_version_impl (inspector , connection )
78+
79+
80+ def _to_sync_url (db_url : str ) -> str :
81+ """Removes '+driver' from SQLAlchemy URL."""
82+ if "://" in db_url :
83+ scheme , _ , rest = db_url .partition ("://" )
84+ if "+" in scheme :
85+ dialect = scheme .split ("+" , 1 )[0 ]
86+ return f"{ dialect } ://{ rest } "
87+ return db_url
88+
89+
90+ def get_db_schema_version (db_url : str ) -> str :
91+ """Reads schema version from DB.
92+
93+ Checks metadata table first and then falls back to table structure.
94+
95+ Args:
96+ db_url: The database URL.
97+
98+ Returns:
99+ The detected schema version as a string. Returns `LATEST_SCHEMA_VERSION`
100+ if it's a new database.
101+ """
102+ engine = None
103+ try :
104+ engine = create_sync_engine (_to_sync_url (db_url ))
105+ with engine .connect () as connection :
106+ inspector = inspect (connection )
107+ return _get_schema_version_impl (inspector , connection )
108+ except Exception :
109+ logger .warning (
110+ "Failed to get schema version from database %s." ,
111+ db_url ,
112+ )
113+ raise
114+ finally :
115+ if engine :
116+ engine .dispose ()
0 commit comments