a7d6d88f6f
CI / changes (push) Has been cancelled
CI / cd libs/checkpoint (push) Has been cancelled
CI / cd libs/checkpoint-conformance (push) Has been cancelled
CI / cd libs/checkpoint-postgres (push) Has been cancelled
CI / cd libs/checkpoint-sqlite (push) Has been cancelled
CI / cd libs/cli (push) Has been cancelled
CI / cd libs/prebuilt (push) Has been cancelled
CI / cd libs/sdk-py (push) Has been cancelled
CI / cd libs/langgraph (push) Has been cancelled
CI / Check SDK methods matching (push) Has been cancelled
CI / Check CLI schema hasn't changed #3.13 (push) Has been cancelled
CI / CLI integration test (push) Has been cancelled
CI / sdk-py integration test (push) Has been cancelled
CI / CI Success (push) Has been cancelled
baseline / benchmark (push) Has been cancelled
Deploy Redirects to GitHub Pages / deploy (push) Has been cancelled
151 lines
6.2 KiB
Markdown
151 lines
6.2 KiB
Markdown
# LangGraph Checkpoint Postgres
|
|
|
|
[](https://pypi.org/project/langgraph-checkpoint-postgres/#history)
|
|
[](https://opensource.org/licenses/MIT)
|
|
[](https://pypistats.org/packages/langgraph-checkpoint-postgres)
|
|
[](https://x.com/langchain_oss)
|
|
|
|
To help you ship LangGraph apps to production faster, check out [LangSmith](https://www.langchain.com/langsmith).
|
|
[LangSmith](https://www.langchain.com/langsmith) is a unified developer platform for building, testing, and monitoring LLM applications.
|
|
|
|
## Quick Install
|
|
|
|
```bash
|
|
uv add langgraph-checkpoint-postgres
|
|
```
|
|
|
|
## 🤔 What is this?
|
|
|
|
This library provides a Postgres implementation of LangGraph's checkpoint saver. Use it when you want LangGraph state persistence backed by Postgres for durable, long-running workflows and agents.
|
|
|
|
By default, `langgraph-checkpoint-postgres` installs `psycopg` (Psycopg 3) without any extras. You can choose a specific installation that best suits your needs in the [Psycopg installation docs](https://www.psycopg.org/psycopg3/docs/basic/install.html), for example `psycopg[binary]`.
|
|
|
|
## 📖 Documentation
|
|
|
|
For full documentation, see the [API reference](https://reference.langchain.com/python/langgraph.checkpoint.postgres). For conceptual guides on persistence and memory, see the [LangGraph Docs](https://docs.langchain.com/oss/python/langgraph/overview).
|
|
|
|
## Security
|
|
|
|
> [!IMPORTANT]
|
|
> Set `LANGGRAPH_STRICT_MSGPACK=true` or pass an explicit `allowed_msgpack_modules` list when creating your checkpointer. This restricts checkpoint deserialization to known-safe types, preventing code execution if the database is compromised. See the [langgraph-checkpoint README](https://github.com/langchain-ai/langgraph/tree/main/libs/checkpoint#serde) for details.
|
|
|
|
## Usage
|
|
|
|
> [!IMPORTANT]
|
|
> When using Postgres checkpointers for the first time, make sure to call `.setup()` method on them to create required tables. See example below.
|
|
|
|
> [!IMPORTANT]
|
|
> When manually creating Postgres connections and passing them to `PostgresSaver` or `AsyncPostgresSaver`, make sure to include `autocommit=True` and `row_factory=dict_row` (`from psycopg.rows import dict_row`). See a full example in this [how-to guide](https://langchain-ai.github.io/langgraph/how-tos/persistence_postgres/).
|
|
>
|
|
> **Why these parameters are required:**
|
|
>
|
|
> - `autocommit=True`: Required for the `.setup()` method to properly commit the checkpoint tables to the database. Without this, table creation may not be persisted.
|
|
> - `row_factory=dict_row`: Required because the PostgresSaver implementation accesses database rows using dictionary-style syntax (e.g., `row["column_name"]`). The default `tuple_row` factory returns tuples that only support index-based access (e.g., `row[0]`), which will cause `TypeError` exceptions when the checkpointer tries to access columns by name.
|
|
>
|
|
> **Example of incorrect usage:**
|
|
>
|
|
> ```python
|
|
> # ❌ This will fail with TypeError during checkpointer operations
|
|
> with psycopg.connect(DB_URI) as conn: # Missing autocommit=True and row_factory=dict_row
|
|
> checkpointer = PostgresSaver(conn)
|
|
> checkpointer.setup() # May not persist tables properly
|
|
> # Any operation that reads from database will fail with:
|
|
> # TypeError: tuple indices must be integers or slices, not str
|
|
> ```
|
|
|
|
```python
|
|
from langgraph.checkpoint.postgres import PostgresSaver
|
|
|
|
write_config = {"configurable": {"thread_id": "1", "checkpoint_ns": ""}}
|
|
read_config = {"configurable": {"thread_id": "1"}}
|
|
|
|
DB_URI = "postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
|
|
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
|
|
# call .setup() the first time you're using the checkpointer
|
|
checkpointer.setup()
|
|
checkpoint = {
|
|
"v": 4,
|
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
"channel_values": {
|
|
"my_key": "meow",
|
|
"node": "node"
|
|
},
|
|
"channel_versions": {
|
|
"__start__": 2,
|
|
"my_key": 3,
|
|
"start:node": 3,
|
|
"node": 3
|
|
},
|
|
"versions_seen": {
|
|
"__input__": {},
|
|
"__start__": {
|
|
"__start__": 1
|
|
},
|
|
"node": {
|
|
"start:node": 2
|
|
}
|
|
},
|
|
}
|
|
|
|
# store checkpoint
|
|
checkpointer.put(write_config, checkpoint, {}, {})
|
|
|
|
# load checkpoint
|
|
checkpointer.get(read_config)
|
|
|
|
# list checkpoints
|
|
list(checkpointer.list(read_config))
|
|
```
|
|
|
|
### Async
|
|
|
|
```python
|
|
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
|
|
|
|
async with AsyncPostgresSaver.from_conn_string(DB_URI) as checkpointer:
|
|
checkpoint = {
|
|
"v": 4,
|
|
"ts": "2024-07-31T20:14:19.804150+00:00",
|
|
"id": "1ef4f797-8335-6428-8001-8a1503f9b875",
|
|
"channel_values": {
|
|
"my_key": "meow",
|
|
"node": "node"
|
|
},
|
|
"channel_versions": {
|
|
"__start__": 2,
|
|
"my_key": 3,
|
|
"start:node": 3,
|
|
"node": 3
|
|
},
|
|
"versions_seen": {
|
|
"__input__": {},
|
|
"__start__": {
|
|
"__start__": 1
|
|
},
|
|
"node": {
|
|
"start:node": 2
|
|
}
|
|
},
|
|
}
|
|
|
|
# store checkpoint
|
|
await checkpointer.aput(write_config, checkpoint, {}, {})
|
|
|
|
# load checkpoint
|
|
await checkpointer.aget(read_config)
|
|
|
|
# list checkpoints
|
|
[c async for c in checkpointer.alist(read_config)]
|
|
```
|
|
|
|
## 📕 Releases & Versioning
|
|
|
|
See our [Releases](https://docs.langchain.com/oss/python/release-policy) and [Versioning](https://docs.langchain.com/oss/python/versioning) policies.
|
|
|
|
## 💁 Contributing
|
|
|
|
As an open-source project in a rapidly developing field, we are extremely open to contributions, whether it be in the form of a new feature, improved infrastructure, or better documentation.
|
|
|
|
For detailed information on how to contribute, see the [Contributing Guide](https://docs.langchain.com/oss/python/contributing/overview).
|