Skip to content

Commit 924c3f9

Browse files
committed
docs: add Database Migration Documentation
1 parent 24f5f1e commit 924c3f9

5 files changed

Lines changed: 256 additions & 1 deletion

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Database Migration Guide: v0.3 to v1.0
2+
3+
The A2A SDK v1.0 introduces significant updates to the database persistence layer, including a new schema for tracking task ownership and protocol versions. This guide provides the necessary steps to migrate your database from v0.3 to the v1.0 persistence model without data loss.
4+
5+
---
6+
7+
## ⚡ Choose Your Migration Strategy
8+
9+
Depending on your application's availability requirements, choose one of the following paths:
10+
11+
| Strategy | Downtime | Complexity | Best For |
12+
| :--- | :--- | :--- | :--- |
13+
| **[Simple Migration](simple_migration.md)** | Short (Restart) | Low | Single-instance apps, non-critical services. |
14+
| **[Zero Downtime Migration](zero_downtime.md)** | None | Medium | Multi-instance, high-availability production environments. |
15+
16+
---
17+
18+
## 🏗️ Technical Overview
19+
20+
The v1.0 database migration involves:
21+
1. **Schema Updates**: Adding `protocol_version`, `owner`, and `last_updated` columns to the `tasks` and `push_notification_configs` tables.
22+
2. **Storage Model**: Transitioning from Pydantic-based JSON to Protobuf-based JSON serialization for better interoperability and performance.
23+
24+
### Rollback & Safety
25+
> [!IMPORTANT]
26+
>
27+
> **Data Backup**: Always perform a full snapshot of your database before starting the migration.
28+
> **Rollback**: To revert the schema, use `uv run a2a-db downgrade -1`.
29+
30+
### Verification
31+
To verify the migration was successful:
32+
- Tables should be updated with new columns: owner, protocol_version, last_updated.
33+
- Inspect the `protocol_version` column in the `tasks` table; entries created before the migration should have `protocol_version` set to `NULL`, entries created during the migration should have `protocol_version` set to `0.3` (if using the zero-downtime migration strategy) and entries created after the migration should have `protocol_version` set to `1.0`.
34+
35+
---
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Simple Migration: v0.3 to v1.0
2+
3+
This guide is for users who can afford a short period of downtime (typically a few minutes) during the migration from A2A protocol v0.3 to v1.0. This is the recommended path for single-instance applications or non-critical services.
4+
5+
> [!WARNING]
6+
> **Safety First:**
7+
> Before proceeding, ensure you have a backup of your database.
8+
9+
---
10+
11+
## 🛠 Prerequisites
12+
13+
### Install Migration Tools
14+
The migration CLI is not included in the base package. Install the `db-cli` extra:
15+
16+
```bash
17+
uv add "a2a-sdk[db-cli]"
18+
# OR
19+
pip install "a2a-sdk[db-cli]"
20+
```
21+
22+
---
23+
24+
## 🚀 Migration Steps
25+
26+
### Step 1: Apply Schema Updates
27+
Run the `a2a-db` tool to update your tables.
28+
29+
```bash
30+
# Run migration against your target database
31+
uv run a2a-db --database-url "your-database-url"
32+
```
33+
34+
> [!NOTE]
35+
>
36+
>For more details on the CLI migration tool, including flags, see the [A2A SDK Database Migrations README](../../../../src/a2a/migrations/README.md).
37+
38+
> [!NOTE]
39+
> All new columns are nullable or have default values.
40+
>
41+
> Protocol v1.0 is designed to be backward compatible by default. After this step, your new v0.1 code will be able to read existing v0.3 entries from the database using a built-in legacy parser.
42+
43+
### Step 2: Verify the Migration
44+
Confirm the schema is at the correct version:
45+
46+
```bash
47+
uv run a2a-db current
48+
```
49+
The output should show the latest revision ID (e.g., `38ce57e08137`).
50+
51+
### Step 3: Update Your Application Code
52+
Upgrade your application to use the v1.0 SDK.
53+
54+
---
55+
56+
## ↩️ Rollback Strategy
57+
58+
If your application fails to start or encounters errors after the migration:
59+
60+
1. **Revert Schema**: Use the `downgrade` command to step back to the v0.3 structure.
61+
```bash
62+
uv run a2a-db downgrade -1
63+
```
64+
2. **Reinstall v0.3 SDK**: Revert your application code to the previous version.
65+
3. **Restart**: Resume operations using the v0.3 SDK.
66+
67+
---
68+
69+
## 🧩 Resources
70+
- **[Zero Downtime Migration](zero_downtime.md)**: If you cannot stop your application.
71+
- **[a2a-db CLI](../../../../src/a2a/migrations/README.md)**: The primary tool for executing schema migrations.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Zero Downtime Migration: v0.3 to v1.0
2+
3+
This guide outlines the strategy for migrating your Agent application from A2A protocol v0.3 to v1.0 without service interruption, even when running multiple distributed instances sharing a single database.
4+
5+
---
6+
7+
> [!WARNING]
8+
> **Safety First:**
9+
> Before proceeding, ensure you have a backup of your database.
10+
11+
---
12+
13+
## 🛠 Prerequisites
14+
15+
### Install Migration Tools
16+
The migration CLI is not included in the base package. Install the `db-cli` extra:
17+
18+
```bash
19+
uv add "a2a-sdk[db-cli]"
20+
# OR
21+
pip install "a2a-sdk[db-cli]"
22+
```
23+
24+
---
25+
26+
## 🏗️ The 3-Step Strategy
27+
28+
Zero-downtime migration requires an "Expand, Migrate, Contract" pattern. It means we first expand the schema, then migrate the code to coexist with the old format, and finally transition fully to the new v1.0 standards.
29+
30+
### Step 1: Expand Schema
31+
32+
Apply the v1.0 schema updates to your database using the `a2a-db` migration tool. This adds new columns (`owner`, `protocol_version`, `last_updated`) while leaving existing v0.3 data intact.
33+
34+
```bash
35+
# Run migration against your target database
36+
uv run a2a-db --database-url "your-database-url"
37+
```
38+
39+
> [!NOTE]
40+
>
41+
>For more details on the CLI migration tool, including flags, see the [A2A SDK Database Migrations README](../../../../src/a2a/migrations/README.md).
42+
43+
> [!NOTE]
44+
> All new columns are nullable or have default values. Your existing v0.3 code will continue to work normally after this step is completed.
45+
>
46+
> Protocol v1.0 is designed to be backward compatible by default. After this step, your new v0.1 code will be able to read existing v0.3 entries from the database using a built-in legacy parser.
47+
48+
#### ✅ How to Verify
49+
Run `uv run a2a-db current` to ensure the migration was applied successfully.
50+
51+
---
52+
53+
### Step 2: Rolling Deployment in Compatibility Mode
54+
55+
In this step, you deploy the v1.0 SDK code but configure it to **write** data in the legacy v0.3 format. This ensures that any v0.3 instances still running in your cluster can read data produced by the new v1.0 instances.
56+
57+
#### Update Initialization Code
58+
Enable the v0.3 conversion utilities in your application entry point (e.g., `main.py`).
59+
60+
```python
61+
from a2a.server.tasks import DatabaseTaskStore, DatabasePushNotificationConfigStore
62+
from a2a.compat.v0_3.conversions import (
63+
core_to_compat_task_model,
64+
core_to_compat_push_notification_config_model,
65+
)
66+
67+
# Initialize stores with compatibility conversion
68+
# The '... # other' represents your existing configuration (engine, table_name, etc.)
69+
task_store = DatabaseTaskStore(
70+
... # other arguments
71+
core_to_model_conversion=core_to_compat_task_model
72+
)
73+
74+
config_store = DatabasePushNotificationConfigStore(
75+
... # other arguments
76+
core_to_model_conversion=core_to_compat_push_notification_config_model
77+
)
78+
```
79+
80+
#### Perform a Rolling Restart
81+
Deploy the new code by restarting your instances one by one.
82+
83+
#### ✅ How to Verify
84+
Verify that v1.0 instances are successfully writing to the database. In the `tasks` and `push_notification_configs` tables, new rows created during this phase should have `protocol_version` set to `0.3`.
85+
86+
---
87+
88+
### Step 3: Transition to v1.0 Mode
89+
90+
Once **100%** of your application instances are running v1.0 code (with compatibility mode enabled), you can switch to the v1.0 write format.
91+
92+
> [!CAUTION]
93+
> **CRITICAL PRE-REQUISITE**: Do NOT start Step 3 until you have confirmed that no v0.3 instances remain. Old v0.3 code cannot parse the new v1.0 native database entries.
94+
95+
#### Disable Compatibility Logic
96+
Remove the `core_to_model_conversion` arguments from your Store constructors.
97+
98+
```python
99+
# Revert to native v1.0 write behavior
100+
task_store = DatabaseTaskStore(engine=engine, ...)
101+
config_store = DatabasePushNotificationConfigStore(engine=engine, ...)
102+
```
103+
104+
#### Perform a Final Rolling Restart
105+
106+
Restart your instances again.
107+
108+
#### ✅ How to Verify
109+
Inspect the `tasks` and `push_notification_configs` tables. New entries should now show `protocol_version` as `1.0`.
110+
111+
---
112+
113+
## 🛠️ Why it Works
114+
115+
The A2A `DatabaseStore` classes follow a version-aware read/write pattern:
116+
117+
1. **Write Logic**: If `core_to_model_conversion` is provided, it is used. Otherwise, it defaults to the v1.0 Protobuf JSON format.
118+
2. **Read Logic**: The store automatically inspects the `protocol_version` column for every row.
119+
* If `NULL` or `0.3`, it uses the internal **v0.3 legacy parser**.
120+
* If `1.0`, it uses the modern **Protobuf parser**.
121+
122+
This allows v1.0 instances to read *all* existing data regardless of when it was written.
123+
124+
125+
## 🧩 Resources
126+
- **[a2a-db CLI](../../../../src/a2a/migrations/README.md)**: The primary tool for executing schema migrations.
127+
- **[Compatibility Conversions](../../../../src/a2a/compat/v0_3/conversions.py)**: Source for classes like `core_to_compat_task_model` used in Step 2.
128+
- **[Task Store Implementation](../../../../src/a2a/server/tasks/database_task_store.py)**: The `DatabaseTaskStore` which handles the version-aware read/write logic.
129+
- **[Push Notification Store Implementation](../../../../src/a2a/server/tasks/database_push_notification_config_store.py)**: The `DatabasePushNotificationConfigStore` which handles the version-aware read/write logic.
130+

src/a2a/a2a_db_cli.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ def create_parser() -> argparse.ArgumentParser:
9393
)
9494
_add_shared_args(down_parser, is_sub=True)
9595

96+
# Current command
97+
current_parser = subparsers.add_parser(
98+
'current', help='Display the current revision for a database'
99+
)
100+
_add_shared_args(current_parser, is_sub=True)
101+
96102
return parser
97103

98104

@@ -152,5 +158,7 @@ def run_migrations() -> None:
152158
elif args.cmd == 'downgrade':
153159
logging.info('Downgrading database to %s', args.revision)
154160
command.downgrade(cfg, args.revision, sql=sql)
161+
elif args.cmd == 'current':
162+
command.current(cfg, verbose=verbose)
155163

156164
logging.info('Done.')

src/a2a/migrations/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,18 @@ uv run a2a-db downgrade base
9191
uv run a2a-db downgrade head:base --sql
9292
```
9393

94-
Note: All flags except `--add_columns_owner_last_updated-default-owner` can be used during rollbacks.
94+
### 6. Verifying Current Status
95+
To see the current revision applied to your database:
96+
97+
```bash
98+
uv run a2a-db current
99+
100+
# To see more details (like revision dates, if available)
101+
uv run a2a-db current -v
102+
```
103+
104+
> [!NOTE]
105+
> All flags except `--add_columns_owner_last_updated-default-owner` can be used during status checks.
95106
96107
---
97108

0 commit comments

Comments
 (0)