Source code for haive.core.persistence.postgres_saver_override
"""PostgreSQL persistence utilities with Pydantic support.This module provides utilities for handling Pydantic models in PostgreSQLpersistence. The main functionality is the JSON encoder configuration thatensures Pydantic models are properly serialized to JSONB columns.The override classes are kept for backward compatibility and as a fallbackwhen using connection strings directly. However, the preferred approach isto configure the connection pool with the configure parameter."""importjsonfromdatetimeimportdatetimeimportpsycopgfromlanggraph.checkpoint.postgresimportPostgresSaverasBasePostgresSaverfromlanggraph.checkpoint.postgres.aioimport(AsyncPostgresSaverasBaseAsyncPostgresSaver,)frompsycopg.rowsimportdict_rowfrompsycopg.types.jsonimportset_json_dumpsfrompydanticimportBaseModel
[docs]defpydantic_aware_json_dumps(obj):"""JSON encoder that handles Pydantic models. This encoder ensures that Pydantic models are properly serialized when stored in PostgreSQL JSONB columns. """classPydanticEncoder(json.JSONEncoder):defdefault(self,o):"""Default. Args: o: [TODO: Add description] """ifisinstance(o,BaseModel):returno.model_dump()ifisinstance(o,datetime):returno.isoformat()returnsuper().default(o)returnjson.dumps(obj,cls=PydanticEncoder)
[docs]defconfigure_postgres_json(connection):"""Configure a PostgreSQL connection to handle Pydantic JSON serialization. Args: connection: A psycopg connection object """set_json_dumps(pydantic_aware_json_dumps,context=connection)
# Override classes for backward compatibility and direct connection string usage
[docs]classPostgresSaverNoPreparedStatements(BasePostgresSaver):"""PostgresSaver that disables prepared statements and handles Pydantic models. This class is kept for backward compatibility and for cases where you need to use from_conn_string directly. The preferred approach is to configure the connection pool with the configure parameter in postgres_config.py. """
[docs]@classmethoddeffrom_conn_string(cls,conn_string:str)->"PostgresSaverNoPreparedStatements":"""Create a PostgresSaver with proper configuration."""conn=psycopg.connect(conn_string,autocommit=True,prepare_threshold=None,row_factory=dict_row,)configure_postgres_json(conn)returncls(conn)
[docs]classAsyncPostgresSaverNoPreparedStatements(BaseAsyncPostgresSaver):"""Async PostgresSaver with proper configuration. This class is kept for backward compatibility and for cases where you need to use from_conn_string directly. The preferred approach is to configure the connection pool with the configure parameter in postgres_config.py. """
[docs]@classmethodasyncdeffrom_conn_string(cls,conn_string:str)->"AsyncPostgresSaverNoPreparedStatements":"""Create an AsyncPostgresSaver with proper configuration."""conn=awaitpsycopg.AsyncConnection.connect(conn_string,autocommit=True,prepare_threshold=None,row_factory=dict_row,)configure_postgres_json(conn)returncls(conn)