> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate a Relational Database into a Knowledge Graph

> Convert a relational database schema and data into a searchable knowledge graph

A focused walkthrough for converting an existing relational database (SQLite or Postgres) into a knowledge graph that can be queried with natural language.

**Before you start:**

* Complete [Quickstart](/getting-started/quickstart) to understand basic operations
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured
* Have connection details for the database you want to migrate

## What This Does

Cognee reads your relational database schema (tables, columns, primary keys, foreign keys) and can map it into graph nodes and edges:

* In **full migration mode**, each **table** becomes a `TableType` node
* Each **row** becomes a `TableRow` node linked to its table
* Non-key column values can become `ColumnValue` nodes linked from each row
* **Foreign key relationships** become edges between row nodes
* Migrated nodes and edges are embedded and indexed for semantic search

After migration, you can query your relational data using `cognee.recall()` with natural language.

## 1. Configure the Migration Database

Set the source database connection in your `.env` file:

<Tabs>
  <Tab title="SQLite">
    ```dotenv theme={null}
    MIGRATION_DB_PROVIDER="sqlite"
    MIGRATION_DB_PATH="/path/to/db/directory"
    MIGRATION_DB_NAME="my_database.sqlite"
    ```
  </Tab>

  <Tab title="Postgres">
    ```dotenv theme={null}
    MIGRATION_DB_PROVIDER="postgres"
    MIGRATION_DB_HOST="127.0.0.1"
    MIGRATION_DB_PORT="5432"
    MIGRATION_DB_USERNAME="myuser"
    MIGRATION_DB_PASSWORD="mypassword"
    MIGRATION_DB_NAME="my_database"
    ```
  </Tab>
</Tabs>

## 2. Run the Migration

```python theme={null}
import asyncio
import os
import tempfile
from pathlib import Path

import cognee
from cognee.api.v1.visualize.visualize import visualize_graph
from cognee.infrastructure.databases.graph import get_graph_engine
from cognee.infrastructure.databases.relational import get_migration_relational_engine
from cognee.infrastructure.databases.relational.config import get_migration_config
from cognee.tasks.ingestion import migrate_relational_database

# Isolate this example from any pre-existing local Cognee state so old SQLite
# metadata files do not interfere with the run.
example_root = Path(tempfile.gettempdir()) / "cognee-relational-migration-example"
os.environ.setdefault("SYSTEM_ROOT_DIRECTORY", str(example_root / "system"))
os.environ.setdefault("DATA_ROOT_DIRECTORY", str(example_root / "data"))
os.environ.setdefault("CACHE_ROOT_DIRECTORY", str(example_root / "cache"))
os.environ.setdefault("ENABLE_BACKEND_ACCESS_CONTROL", "false")

async def main():
    migration_config = get_migration_config()
    migration_config.migration_db_provider = os.environ.get("MIGRATION_DB_PROVIDER", "sqlite")
    migration_config.migration_db_path = os.environ.get("MIGRATION_DB_PATH", "/path/to/db")
    migration_config.migration_db_name = os.environ.get(
        "MIGRATION_DB_NAME", "my_database.sqlite"
    )

    # Start from a clean local state for repeatable runs.
    await cognee.forget(everything=True)

    # Extract the schema from the source database
    engine = get_migration_relational_engine()
    schema = await engine.extract_schema()
    print(f"Loaded schema with {len(schema)} tables: {sorted(schema)}")

    # Migrate schema + all rows into the graph
    graph = await get_graph_engine()
    nodes, edges = await migrate_relational_database(graph, schema=schema)
    print(f"Migrated graph: {len(nodes)} nodes / {len(edges)} edges")

    # Query the migrated data
    results = await cognee.recall(
        query_text="What data does this database contain?",
        top_k=100,
    )
    print("Recall results:")
    print(results)

    # Visualize the migrated graph
    graph_path = Path(__file__).resolve().parent / "relational_migration_graph.html"
    graph_html = await visualize_graph(str(graph_path))
    graph_path.write_text(graph_html, encoding="utf-8")
    print(f"Graph visualization saved at: {graph_path}")

asyncio.run(main())
```

<Note>
  The migration pipeline itself uses lower-level APIs because it is importing an external relational schema directly into the graph. Once the graph is built, prefer `cognee.recall()` as the default query interface in v1.0. Set `top_k` higher (100-200) for broad exploratory queries over large databases, and lower (20-50) for specific lookups to keep LLM context manageable. The example above also isolates Cognee's local state in a temp directory so repeated runs do not pick up stale metadata from earlier experiments.
</Note>

## Additional information

<AccordionGroup>
  <Accordion title="Migration Modes">
    `migrate_relational_database` has two modes controlled by the `schema_only` flag:

    | Mode               | Flag                | What is migrated                                                                                  |
    | ------------------ | ------------------- | ------------------------------------------------------------------------------------------------- |
    | **Full** (default) | `schema_only=False` | `TableType`, `TableRow`, optional `ColumnValue`, and foreign-key edges                            |
    | **Schema only**    | `schema_only=True`  | `DatabaseSchema`, `SchemaTable`, and `SchemaRelationship` datapoints for structural understanding |

    Schema-only mode does **not** create `TableRow` nodes for every record. Instead, it ingests schema-level datapoints and attaches up to a few sample rows as metadata on each `SchemaTable` node. Use it when you want to explore table structure and relationships without migrating the full dataset:

    ```python theme={null}
    await migrate_relational_database(graph, schema=schema, schema_only=True)
    ```

    This is especially useful for large databases when your questions are structural, for example:

    * "What tables exist in this database?"
    * "Which tables are connected by foreign keys?"
    * "What kind of data does the `invoices` table contain?"
  </Accordion>

  <Accordion title="Mixing migration and application DB providers">
    `MIGRATION_DB_PROVIDER` is independent of `DB_PROVIDER` — Cognee builds a separate engine for each from its own config (`MigrationConfig` vs `RelationalConfig`). You can freely combine providers: for example, keep Cognee's application metadata in Postgres while migrating from a local SQLite file.

    ```dotenv theme={null}
    # Application DB — Cognee's internal metadata store
    DB_PROVIDER="postgres"
    DB_NAME="cognee_db"
    DB_HOST="127.0.0.1"
    DB_PORT="5432"
    DB_USERNAME="cognee"
    DB_PASSWORD="cognee"

    # Migration DB — source data in a SQLite file
    MIGRATION_DB_PROVIDER="sqlite"
    MIGRATION_DB_PATH="/path/to/db/directory"
    MIGRATION_DB_NAME="my_app_data.sqlite"
    ```

    The reverse (`DB_PROVIDER="sqlite"` with `MIGRATION_DB_PROVIDER="postgres"`) is equally valid. See [Relational Databases](/setup-configuration/relational-databases) for additional same-server and cross-server combinations.
  </Accordion>

  <Accordion title="Visualize the Result">
    ```python theme={null}
    from cognee.api.v1.visualize.visualize import visualize_graph
    from pathlib import Path

    graph_path = Path("./migration_graph.html")
    graph_html = await visualize_graph(str(graph_path))
    graph_path.write_text(graph_html, encoding="utf-8")
    ```

    This generates an HTML file you can open in a browser to explore the graph structure. See [Graph Visualization](/guides/graph-visualization) for more options.
  </Accordion>
</AccordionGroup>

<Columns cols={3}>
  <Card title="Relational Databases" icon="database" href="/setup-configuration/relational-databases">
    Configure SQLite and Postgres connections
  </Card>

  <Card title="Recall and Search" icon="search" href="/guides/search-basics">
    Learn the current recall flow and lower-level search options
  </Card>

  <Card title="Graph Visualization" icon="network" href="/guides/graph-visualization">
    Explore your knowledge graph visually
  </Card>
</Columns>
