2626from typing import TypeVar
2727
2828from google .adk .platform import time as platform_time
29+ from google .adk .platform import uuid as platform_uuid
2930
3031try :
3132 from sqlalchemy import delete
@@ -434,9 +435,12 @@ async def create_session(
434435 # 4. Build the session object with generated id
435436 # 5. Return the session
436437 await self ._prepare_tables ()
438+ has_user_provided_id = session_id is not None
439+ if session_id is None :
440+ session_id = platform_uuid .new_uuid ()
437441 schema = self ._get_schema_classes ()
438442 async with self ._rollback_on_exception_session () as sql_session :
439- if session_id and await sql_session .get (
443+ if has_user_provided_id and await sql_session .get (
440444 schema .StorageSession , (app_name , user_id , session_id )
441445 ):
442446 raise AlreadyExistsError (
@@ -484,15 +488,17 @@ async def create_session(
484488 update_time = now ,
485489 )
486490 sql_session .add (storage_session )
487- await sql_session .commit ()
488491
489492 # Merge states for response
490493 merged_state = _merge_state (
491494 storage_app_state .state , storage_user_state .state , session_state
492495 )
496+ # Call to_session before commit to avoid post-commit lazy-load.
497+ await sql_session .flush ()
493498 session = storage_session .to_session (
494- state = merged_state , is_sqlite = is_sqlite
499+ state = merged_state , is_sqlite = is_sqlite , is_postgresql = is_postgresql
495500 )
501+ await sql_session .commit ()
496502 return session
497503
498504 @override
@@ -555,8 +561,12 @@ async def get_session(
555561 # Convert storage session to session
556562 events = [e .to_event () for e in reversed (storage_events )]
557563 is_sqlite = self .db_engine .dialect .name == _SQLITE_DIALECT
564+ is_postgresql = self .db_engine .dialect .name == _POSTGRESQL_DIALECT
558565 session = storage_session .to_session (
559- state = merged_state , events = events , is_sqlite = is_sqlite
566+ state = merged_state ,
567+ events = events ,
568+ is_sqlite = is_sqlite ,
569+ is_postgresql = is_postgresql ,
560570 )
561571 return session
562572
@@ -603,12 +613,17 @@ async def list_sessions(
603613
604614 sessions = []
605615 is_sqlite = self .db_engine .dialect .name == _SQLITE_DIALECT
616+ is_postgresql = self .db_engine .dialect .name == _POSTGRESQL_DIALECT
606617 for storage_session in results :
607618 session_state = storage_session .state
608619 user_state = user_states_map .get (storage_session .user_id , {})
609620 merged_state = _merge_state (app_state , user_state , session_state )
610621 sessions .append (
611- storage_session .to_session (state = merged_state , is_sqlite = is_sqlite )
622+ storage_session .to_session (
623+ state = merged_state ,
624+ is_sqlite = is_sqlite ,
625+ is_postgresql = is_postgresql ,
626+ )
612627 )
613628 return ListSessionsResponse (sessions = sessions )
614629
@@ -660,6 +675,7 @@ async def append_event(self, session: Session, event: Event) -> Event:
660675 # 3. Store the new event.
661676 schema = self ._get_schema_classes ()
662677 is_sqlite = self .db_engine .dialect .name == _SQLITE_DIALECT
678+ is_postgresql = self .db_engine .dialect .name == _POSTGRESQL_DIALECT
663679 use_row_level_locking = self ._supports_row_level_locking ()
664680
665681 state_delta = event .actions .state_delta if event .actions .state_delta else {}
@@ -685,7 +701,9 @@ async def append_event(self, session: Session, event: Event) -> Event:
685701 storage_session = storage_session_result .scalars ().one_or_none ()
686702 if storage_session is None :
687703 raise ValueError (f"Session { session .id } not found." )
688- storage_update_time = storage_session .get_update_timestamp (is_sqlite )
704+ storage_update_time = storage_session .get_update_timestamp (
705+ is_sqlite = is_sqlite , is_postgresql = is_postgresql
706+ )
689707 storage_update_marker = storage_session .get_update_marker ()
690708
691709 storage_app_state = await _select_required_state (
@@ -751,7 +769,8 @@ async def append_event(self, session: Session, event: Event) -> Event:
751769 storage_session .state | state_deltas ["session" ]
752770 )
753771
754- if is_sqlite :
772+ is_postgresql = self .db_engine .dialect .name == _POSTGRESQL_DIALECT
773+ if is_sqlite or is_postgresql :
755774 update_time = datetime .fromtimestamp (
756775 event .timestamp , timezone .utc
757776 ).replace (tzinfo = None )
@@ -763,7 +782,9 @@ async def append_event(self, session: Session, event: Event) -> Event:
763782 # Read revision fields before commit. Post-commit ORM attribute access
764783 # can lazy-load expired columns and trigger MissingGreenlet with asyncpg
765784 # when pool_pre_ping is enabled.
766- last_update_time = storage_session .get_update_timestamp (is_sqlite )
785+ last_update_time = storage_session .get_update_timestamp (
786+ is_sqlite = is_sqlite , is_postgresql = is_postgresql
787+ )
767788 storage_update_marker = storage_session .get_update_marker ()
768789 await sql_session .commit ()
769790
0 commit comments