Database Migrations

Migrate Agno database tables between versions.

You can expect the schemas in your Agno database tables to be stable across versions.

However, in future versions, we may occasionally update or add new columns or tables.

To apply migrations, Agno provides two options:

  • Use the AgentOS migration endpoints: This is the easiest option when using AgentOS. You just need to make a POST request.
  • Migrate manually using the MigrationManager: If you prefer a more controlled migration experience, you can use the MigrationManager class to upgrade or downgrade your schemas.

Using the AgentOS Migration Endpoints

If you are using the AgentOS, you can handle your migration needs via the migration endpoints.

You can read more about it in the AgentOS Database Migrations page.

Migrate manually using the MigrationManager

All migrations are ultimately handled by the MigrationManager class.

You can use it directly to have total control over your migration process, or use one of the supporting scripts we provide.

Using it directly looks like this:

import asyncio

from agno.db.migrations.manager import MigrationManager
from agno.db.postgres import AsyncPostgresDb

# The database you want to migrate
db = AsyncPostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

async def run_migrations():
    await MigrationManager(db).up()

if __name__ == "__main__":
    asyncio.run(run_migrations())

Install the selected database adapter's dependencies, configure your database URL, and take a restorable backup before running migrations. Supporting scripts are in libs/agno/migrations.

About the MigrationManager

The MigrationManager:

  1. Creates an agno_schema_versions table to track schema versions for each table
  2. Checks the current schema version of each table
  3. Applies migrations in order from the current version to the target version
  4. Updates the schema version record after successful migration
  5. Supports both synchronous and asynchronous database operations

The v3.0 migration supports these synchronous databases:

  • PostgreSQL, SQLite, MySQL, and SingleStore
  • MongoDB, Firestore, Redis, and Valkey
  • JSON, Google Cloud Storage JSON, and in-memory storage
  • DynamoDB and SurrealDB

The asynchronous database classes AsyncPostgresDb, AsyncSqliteDb, AsyncMySQLDb, and AsyncMongoDb are also supported.

  • We recommend avoiding creating columns in your database manually. This can cause the migration manager to fail.
  • Ensure the schema versions in the agno_schema_versions table are correct.

See the MigrationManager page for more information.

Upgrade a specific table

You can also upgrade a specific table:

import asyncio

from agno.db.migrations.manager import MigrationManager
from agno.db.postgres import AsyncPostgresDb

# The database you want to migrate
db = AsyncPostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

async def run_migrate_table():
    # This will migrate the memories table to the latest version
    await MigrationManager(db).up(table_type="memories")


if __name__ == "__main__":
    asyncio.run(run_migrate_table())

The supported table types are: memories, sessions, metrics, evals, knowledge, approvals, components, schedules, schedule_runs, and learnings.

To stop an upgrade at an intermediate schema, pass target_version to up() instead of the latest-version call. up() applies forward migrations; it does not downgrade a database already above that target.

Reverting Migrations

You can also use the MigrationManager class to revert a migration:

import asyncio

from agno.db.migrations.manager import MigrationManager
from agno.db.postgres import AsyncPostgresDb

# The database you want to migrate
db = AsyncPostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

async def run_revert_migrations():
    await MigrationManager(db).down(target_version="2.0.0")

if __name__ == "__main__":
    asyncio.run(run_revert_migrations())

Some migrations are irreversible. In v3.0, the learnings entity-memory re-key cannot be moved back to the shared pre-v3 key. MigrationManager.down() leaves that table unchanged. Back up the database before downgrading.

Troubleshooting

If you continue to see errors and are not able to read or write to the database, it's likely due to a mismatch between the schema version and the actual schema of the table.

Inspect the actual table schema, its recorded version, and the applicable migration before choosing a repair. force=True bypasses the initial skip check, but up() still selects only migrations newer than the recorded version. It cannot reapply an already stamped migration. A table for which the adapter reports no schema version is skipped even with force=True.

Migrating from Agno v1 to v2

If you started using Agno during its v1 and want to move to v2, we have a migration script that can help you update your database tables.

Follow the staged Migrating to Agno v2 guide in an Agno v2 environment first, then migrate v2 data to v3. Do not run the v1-to-v2 helper under current Agno v3: its bulk session write path can omit legacy run history while reporting migrated session records.