Skip to content

Conversation

@achilleasatha
Copy link

Adopt Alembic as the migration framework for DatabaseSessionService, replacing manual ALTER TABLE operations.

This enables automatic schema tracking, upgrade/downgrade support, and Kubernetes Helm hook integration for production deployments.

Addresses #3343


  • AlembicMigrationRunner
    • Wraps Alembic’s command API with programmatic config (instead of alembic.ini)
    • Ships migrations inside the package
  • V1 baseline migration
    • Creates all current schema tables
  • V0 → V1 in-place bootstrap
    • Migrates pickle-based databases to JSON
    • No separate destination database required
  • env.py and script.py.mako
    • Support both online and offline migration modes

  • upgrade — Apply pending migrations with auto-bootstrap for existing DBs
  • downgrade — Roll back by revision spec
  • check — Exit 0 if up-to-date, 1 if pending (CI/CD gate)
  • stamp — Bootstrap Alembic tracking for existing databases
  • generate — Create new migration scripts (autogenerate or template)

  • _ensure_alembic_tracking() stamps baseline after table creation
  • V0 databases auto-migrate to V1 on first access
  • ADK_AUTO_MIGRATE_DB=true
    • Runs pending migrations on startup
  • ADK_AUTO_MIGRATE_DB=false (default)
    • Raises RuntimeError if schema is behind

  • get_alembic_revision()
  • is_alembic_managed()
  • is_alembic_managed_from_url()

  • unit tests for AlembicMigrationRunner (SQLite)
  • CLI command tests covering all subcommands and edge cases
  • integration tests across SQLite / PostgreSQL / MySQL
  • Updated test_database_schema.py for V0 auto-migration behavior
  • GHA workflow:
    • PostgreSQL 15–17
    • MySQL 8.0 / 8.4 / 9.2
    • Python 3.10–3.14
  • docker-compose.yml for local integration testing / development

  • migration_guide.md — User-facing upgrade and CLI reference
  • helm_migration_guide.md — Kubernetes Job and Cloud SQL Proxy examples
  • migration/README.md — Contributor workflow for adding schema versions

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

  • Closes: #issue_number
  • Related: #issue_number

2. Or, if no issue exists, describe the change:

If applicable, please follow the issue templates to provide as much detail as
possible.

Problem:
A clear and concise description of what the problem is.

Solution:
A clear and concise description of what you want to happen and why you choose
this solution.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required
for all PRs that are not small documentation or typo fixes.

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Please include a summary of passed pytest results.

Manual End-to-End (E2E) Tests:

Please provide instructions on how to manually test your changes, including any
necessary setup or configuration. Please provide logs or screenshots to help
reviewers better understand the fix.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

Add any other context or screenshots about the feature request here.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @achilleasatha, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modernizes the DatabaseSessionService by integrating Alembic for robust and automated database schema management. This change moves away from error-prone manual schema updates, providing a standardized, version-controlled approach to database evolution. It introduces new CLI tools for migration control and supports automatic in-place upgrades for existing databases, streamlining deployment and maintenance processes.

Highlights

  • Alembic Adoption: Adopted Alembic as the official database migration framework, replacing manual ALTER TABLE operations for DatabaseSessionService.
  • Automated Schema Management: Introduced automatic schema tracking, upgrade/downgrade capabilities, and integration with Kubernetes Helm hooks for production deployments.
  • In-place V0 to V1 Migration: Implemented an in-place bootstrapping mechanism to migrate existing V0 (pickle-based) databases to the V1 (JSON-based) schema automatically.
  • New CLI Commands: Added new adk migrate CLI subcommands (upgrade, downgrade, check, stamp, generate) for comprehensive database schema management.
  • Configurable Auto-Migration: Introduced the ADK_AUTO_MIGRATE_DB environment variable to enable or disable automatic database migration on application startup.
  • Enhanced Documentation: Provided new user-facing guides for general database migration and specific instructions for Kubernetes Helm deployments.
  • Expanded Test Coverage: Added extensive unit and integration tests covering SQLite, PostgreSQL, and MySQL to ensure robust migration functionality.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • docs/helm_migration_guide.md
    • New file providing guidance on integrating database migrations into Kubernetes deployments using Helm hooks.
  • docs/migration_guide.md
    • New user-facing guide detailing how to configure and run database migrations with Alembic, including upgrading from older ADK versions.
  • pyproject.toml
    • Added alembic as a project dependency.
  • src/google/adk/cli/cli_tools_click.py
    • Extended the adk migrate CLI group with new commands: upgrade, downgrade, check, stamp, and generate for Alembic operations.
  • src/google/adk/sessions/alembic_runner.py
    • New module containing the AlembicMigrationRunner class, which programmatically interfaces with Alembic, manages migration scripts, and handles in-place V0 to V1 schema transformations.
  • src/google/adk/sessions/database_session_service.py
    • Modified _prepare_tables to incorporate Alembic tracking and conditional auto-migration based on the ADK_AUTO_MIGRATE_DB environment variable.
  • src/google/adk/sessions/migration/_schema_check_utils.py
    • Updated to include functions for checking Alembic management status (is_alembic_managed, get_alembic_revision) and revised warning messages for V0 schema.
  • src/google/adk/sessions/migration/env.py
    • New Alembic environment configuration file, enabling programmatic setup for online and offline migration modes.
  • src/google/adk/sessions/migration/script.py.mako
    • New Mako template used by Alembic to generate new migration scripts.
  • src/google/adk/sessions/migration/versions/001_baseline_v1_schema.py
    • New initial migration script that defines the V1 database schema, serving as the baseline for all future migrations.
  • src/google/adk/sessions/migration/versions/init.py
    • New empty __init__.py file to make the versions directory a Python package.
  • tests/integration/sessions/init.py
    • New empty __init__.py file for the integration tests directory.
  • tests/integration/sessions/docker-compose.yml
    • New Docker Compose configuration for setting up PostgreSQL and MySQL databases for integration testing.
  • tests/integration/sessions/test_database_migration_integration.py
    • New integration tests verifying the full migration lifecycle (upgrade, downgrade, data preservation) across SQLite, PostgreSQL, and MySQL.
  • tests/unittests/sessions/migration/test_alembic_runner.py
    • New unit tests specifically for the AlembicMigrationRunner class, covering its core functionalities.
  • tests/unittests/sessions/migration/test_cli_migrate_commands.py
    • New unit tests for the newly added adk migrate CLI subcommands, ensuring their correct behavior and error handling.
  • tests/unittests/sessions/migration/test_database_schema.py
    • Updated an existing test case to reflect the new V0 database auto-migration behavior to V1.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/test-migrations.yml
Activity
  • Comprehensive unit tests for the AlembicMigrationRunner class have been added, specifically covering SQLite database interactions.
  • Extensive CLI command tests have been implemented to validate all new adk migrate subcommands and their various edge cases.
  • New integration tests have been developed to verify the migration functionality across SQLite, PostgreSQL, and MySQL databases, ensuring cross-database compatibility.
  • The test_database_schema.py file was updated to accurately reflect the new V0 auto-migration behavior, ensuring existing V0 databases are correctly handled.
  • A GitHub Actions (GHA) workflow has been configured to run tests against PostgreSQL (versions 15–17), MySQL (versions 8.0, 8.4, 9.2), and Python (versions 3.10–3.14), providing robust CI coverage.
  • A docker-compose.yml file was added to simplify local integration testing and development setup for different database environments.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Adopt **Alembic** as the migration framework for `DatabaseSessionService`, replacing manual `ALTER TABLE` operations.

This enables automatic schema tracking, upgrade/downgrade support, and Kubernetes Helm hook integration for production deployments.

Addresses google#3343

---

- **AlembicMigrationRunner**
  - Wraps Alembic’s command API with programmatic config (instead of `alembic.ini`)
  - Ships migrations inside the package
- **V1 baseline migration**
  - Creates all current schema tables
- **V0 → V1 in-place bootstrap**
  - Migrates pickle-based databases to JSON
  - No separate destination database required
- `env.py` and `script.py.mako`
  - Support both online and offline migration modes

---

- `upgrade` — Apply pending migrations with auto-bootstrap for existing DBs
- `downgrade` — Roll back by revision spec
- `check` — Exit `0` if up-to-date, `1` if pending (CI/CD gate)
- `stamp` — Bootstrap Alembic tracking for existing databases
- `generate` — Create new migration scripts (autogenerate or template)

---

- `_ensure_alembic_tracking()` stamps baseline after table creation
- V0 databases auto-migrate to V1 on first access
- `ADK_AUTO_MIGRATE_DB=true`
  - Runs pending migrations on startup
- `ADK_AUTO_MIGRATE_DB=false` (default)
  - Raises `RuntimeError` if schema is behind

---

- `get_alembic_revision()`
- `is_alembic_managed()`
- `is_alembic_managed_from_url()`

---

- unit tests for `AlembicMigrationRunner` (SQLite)
- CLI command tests covering all subcommands and edge cases
- integration tests across SQLite / PostgreSQL / MySQL
- Updated `test_database_schema.py` for V0 auto-migration behavior
- GHA workflow:
  - PostgreSQL 15–17
  - MySQL 8.0 / 8.4 / 9.2
  - Python 3.10–3.14
- `docker-compose.yml` for local integration testing / development

---

- `migration_guide.md` — User-facing upgrade and CLI reference
- `helm_migration_guide.md` — Kubernetes Job and Cloud SQL Proxy examples
- `migration/README.md` — Contributor workflow for adding schema versions
@adk-bot adk-bot added the services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc label Feb 7, 2026
@achilleasatha achilleasatha force-pushed the feat/issue-3343-adopt-alembic-for-database-migrations branch from 530c7ee to 6066b3f Compare February 7, 2026 18:57
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent and comprehensive pull request that introduces Alembic for database schema migrations. The implementation is robust, with a new AlembicMigrationRunner to handle migrations programmatically, new CLI commands for managing migrations, and automatic migration capabilities within DatabaseSessionService. The addition of extensive unit and integration tests across multiple database backends is particularly impressive and ensures the reliability of this new system. The documentation updates are also very clear and helpful for both users and contributors. I have a few minor suggestions for the documentation and one security note regarding the use of pickle during the V0 to V1 data migration.

if actions_raw is not None:
try:
if isinstance(actions_raw, bytes):
obj = pickle.loads(actions_raw) # noqa: S301
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

Using pickle.loads() on data read from the database can introduce a security vulnerability (Insecure Deserialization). If an attacker can write a malicious pickle object to the database, they could achieve remote code execution when this migration script is run.

While I understand this is necessary for migrating away from the insecure pickle format, it's important to acknowledge and mitigate the risk. Please ensure that access to the database is strictly controlled, especially during the migration process.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm not sure what gemini is trying to get out of this. It already acknowledges this is a requirement so we can move away from this. So we will inevitably need to perform the unsafe operation to do the V0->V1 migration. Best I can think of is to explicitly block dangerous types 🤷

Addressed in commit: 45d77e0

@achilleasatha
Copy link
Author

Note in this draft version I've included in /docs some documentation that should be migrated to https://github.com/google/adk-docs before this is finalised.

Including it here for now so that this is self-contained.

I am not addressing as part of this PR the locking mechanism discussed in #4387

achilleasatha and others added 3 commits February 7, 2026 19:01
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
return

db_url = str(self.db_engine.url)
runner = AlembicMigrationRunner(db_url)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to have the runner use self.db_engine directly instead of using the url to create new engines. With that change, kwargs used to create the engine in the db session service init (which can be required for connection) would still be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants