-
Notifications
You must be signed in to change notification settings - Fork 3.2k
[Bug] DatabaseSessionService fails with MySQL/pymysql: TypeError 'tuple' object cannot be interpreted as an integer when serializing EventActions #3294
Copy link
Copy link
Closed
Labels
services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc
Description
Bug Description
When using DatabaseSessionService with MySQL and pymysql driver, attempting to save events fails with a serialization error:
TypeError: 'tuple' object cannot be interpreted as an integer
[SQL: INSERT INTO events (..., actions, ...) VALUES (...)]
This occurs when ADK tries to serialize EventActions objects to the actions LONGBLOB field in the database.
Steps to Reproduce
import asyncio
from google.adk.events import Event, EventActions
from google.adk.sessions import DatabaseSessionService
import time
import uuid
async def reproduce_bug():
# Initialize DatabaseSessionService with MySQL
db_url = "mysql+pymysql://user:password@host:3306/database"
db_service = DatabaseSessionService(db_url=db_url)
# Create a session
session = await db_service.create_session(
app_name="test_app",
user_id="test_user",
session_id=f"test_{uuid.uuid4().hex}"
)
# Try to save an event with EventActions
event = Event(
invocation_id=f"inv_{uuid.uuid4().hex}",
author="system",
actions=EventActions(state_delta={'key': 'value'}),
timestamp=time.time()
)
# This will fail with TypeError
await db_service.append_event(session=session, event=event)
asyncio.run(reproduce_bug())Error Message
Traceback (most recent call last):
File "/path/to/sqlalchemy/engine/base.py", line 1815, in _execute_context
context = constructor(...)
File "/path/to/sqlalchemy/engine/default.py", line 1527, in <dictcomp>
flattened_processors[key](compiled_params[key])
File "/path/to/sqlalchemy/sql/sqltypes.py", line 918, in process
return DBAPIBinary(value)
File "/path/to/pymysql/__init__.py", line 129, in Binary
return bytes(x)
TypeError: 'tuple' object cannot be interpreted as an integer
[SQL: INSERT INTO events (id, app_name, user_id, session_id, invocation_id, author, actions, ...) VALUES (...)]
Root Cause
The issue occurs in the serialization chain:
- ADK uses
pickleto serializeEventActionsobjects - SQLAlchemy 2.0 processes BLOB columns and calls
pymysql.Binary() - pymysql's
Binary()function expects bytes or an iterable of integers, but receives a complex pickled object (tuple) bytes(tuple)fails with the TypeError
Environment
- ADK Version: 1.17.0
- SQLAlchemy Version: 2.0.44
- pymysql Version: 1.1.2
- MySQL Version: 8.0
- Python Version: 3.11.14
- Operating System: macOS / Linux
Expected Behavior
DatabaseSessionService should correctly serialize and deserialize EventActions objects when using MySQL with pymysql driver, just as it works with other database backends.
Current Workaround
We've created a temporary patch that intercepts SQLAlchemy's parameter processing:
import pickle
from sqlalchemy import event
from sqlalchemy.engine import Engine
def _binary_value_converter(value):
if isinstance(value, bytes):
return value
return pickle.dumps(value)
@event.listens_for(Engine, "before_cursor_execute", retval=True)
def _patch_binary_params(conn, cursor, statement, parameters, context, executemany):
if isinstance(parameters, dict) and 'actions' in parameters:
if not isinstance(parameters['actions'], bytes):
parameters['actions'] = _binary_value_converter(parameters['actions'])
return statement, parametersFull patch implementation available at: [link to our patch file if you want to share]
Suggested Solution
Possible fixes:
- Option 1: In
DatabaseSessionService, explicitly pickleEventActionsbefore passing to SQLAlchemy - Option 2: Use SQLAlchemy's custom type with proper
process_bind_paramandprocess_result_valuemethods - Option 3: Document pymysql incompatibility and recommend using
mysqlclientor PostgreSQL instead
Additional Context
- This issue does NOT occur with PostgreSQL
- The problem is specific to the combination of SQLAlchemy 2.0 + pymysql + MySQL
- The
eventstable'sactionscolumn is defined as LONGBLOB in MySQL - Both writing (insert) and reading (deserialize) are affected
Questions
- Is MySQL with pymysql officially supported by ADK?
- If yes, should we expect this to work out of the box?
- Are there any plans to improve database driver compatibility testing?
Related Issues
- Potentially related to SQLAlchemy 2.0 migration changes
- May affect other BLOB columns in the schema (content, metadata fields, etc.)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc