# SQLite Schema Used by code-review-graph: Knowledge Graph Database Design

> Explore the SQLite schema for code-review-graph. Discover how nodes and edges tables store code elements and relationships in this knowledge graph database design.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: architecture
- Published: 2026-08-15

---

**The code-review-graph project persists its knowledge graph in a SQLite database with two primary tables—`nodes` for code elements and `edges` for relationships—defined in the `_SCHEMA_SQL` string within [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py).**

The open-source code-review-graph repository implements a relational storage layer to capture code structure and dependencies extracted from software projects. Understanding the exact SQLite schema used by code-review-graph is essential for querying call hierarchies, analyzing import graphs, and extending the tool's static analysis capabilities. The schema is initialized automatically when creating a `GraphStore` instance and includes strategic indexes to accelerate traversal queries.

## The `nodes` Table Schema

The `nodes` table stores one row per discrete code element, spanning files, classes, functions, types, and test definitions. According to the source code in [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) (lines 42-73), this table captures location metadata, signature details, and parent-child hierarchies through 16 normalized columns.

```sql
CREATE TABLE IF NOT EXISTS nodes (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    kind TEXT NOT NULL,          -- File, Class, Function, Type, Test
    name TEXT NOT NULL,
    qualified_name TEXT NOT NULL UNIQUE,
    file_path TEXT NOT NULL,
    line_start INTEGER,
    line_end INTEGER,
    language TEXT,
    parent_name TEXT,
    params TEXT,
    return_type TEXT,
    modifiers TEXT,
    is_test INTEGER DEFAULT 0,
    file_hash TEXT,
    extra TEXT DEFAULT '{}',
    updated_at REAL NOT NULL
);

```

**Key design decisions** in this schema include:

- **`qualified_name`** functions as a unique natural key, combining namespaces like `my_pkg.utils.process_data` to prevent collisions across modules.
- **`kind`** discriminates between entity types (File, Class, Function, Type, Test) enabling filtered graph traversals.
- **`file_hash`** and **`updated_at`** facilitate incremental updates and cache invalidation during repeated parsing runs.
- **`extra`** stores flexible JSON metadata for language-specific attributes without schema migrations.

The table maintains three indexes on `file_path`, `kind`, and `qualified_name` to optimize file-scoped queries and symbol lookups.

## The `edges` Table Schema

The `edges` table records directed relationships between code elements, supporting graph traversals for impact analysis and dependency mapping. This schema implements a standard triple-store pattern with additional provenance metadata.

```sql
CREATE TABLE IF NOT EXISTS edges (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    kind TEXT NOT NULL,           -- CALLS, IMPORTS_FROM, INHERITS, REFERENCES, etc.
    source_qualified TEXT NOT NULL,
    target_qualified TEXT NOT NULL,
    file_path TEXT NOT NULL,
    line INTEGER DEFAULT 0,
    extra TEXT DEFAULT '{}',
    confidence REAL DEFAULT 1.0,
    confidence_tier TEXT DEFAULT 'EXTRACTED',
    updated_at REAL NOT NULL
);

```

**Critical fields** for relationship analysis:

- **`source_qualified`** and **`target_qualified`** reference the `qualified_name` column in the `nodes` table, creating a foreign-key-like linkage without strict SQL constraints.
- **`kind`** categorizes the relationship semantics, supporting values like `CALLS`, `IMPORTS_FROM`, `INHERITS`, `REFERENCES`, `CONTAINS`, `TESTED_BY`, and `DEPENDS_ON`.
- **`confidence`** and **`confidence_tier`** track extraction certainty, allowing downstream filters to distinguish between statically extracted facts and inferred dependencies.

Four composite indexes cover `source_qualified`, `target_qualified`, `kind`, and `file_path` to accelerate bidirectional traversal queries and file-scope edge filtering.

## Schema Implementation and Migrations

The complete schema definition resides in the `_SCHEMA_SQL` constant inside [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py). When initializing a `GraphStore` with a `Path` object, the constructor executes this schema against the SQLite database file, creating tables only if they do not exist.

Schema evolution is managed by [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py), which maintains a `metadata` table tracking the current schema version. This migration system applies incremental updates while preserving existing graph data across tool updates.

## Working with the SQLite Schema in Python

The `GraphStore` class provides type-safe methods to interact with the underlying schema without writing raw SQL. The following example demonstrates inserting nodes and edges using the `NodeInfo` and `EdgeInfo` data structures defined in [`code_review_graph/parser.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/parser.py):

```python
from pathlib import Path
from code_review_graph.graph import GraphStore, NodeInfo, EdgeInfo

# Initialize the SQLite-backed graph store

store = GraphStore(Path("tmp/graph.db"))

# Insert a function node

node = NodeInfo(
    kind="Function",
    name="process_data",
    qualified_name="my_pkg.utils.process_data",
    file_path="my_pkg/utils.py",
    line_start=10,
    line_end=25,
    language="python",
    parent_name=None,
    params="data: pd.DataFrame",
    return_type="pd.DataFrame",
    is_test=False,
    extra={},
)
node_id = store.upsert_node(node, file_hash="abcd1234")
print(f"Node ID: {node_id}")

# Insert a CALLS relationship edge

edge = EdgeInfo(
    kind="CALLS",
    source_qualified="my_pkg.main.run",
    target_qualified="my_pkg.utils.process_data",
    file_path="my_pkg/main.py",
    line=42,
    extra={},
    confidence=0.95,
    confidence_tier="EXTRACTED",
)
edge_id = store.upsert_edge(edge)
print(f"Edge ID: {edge_id}")

# Query all functions in the graph

functions = store.query_nodes(kind="Function")
for fn in functions:
    print(fn.qualified_name)

store.close()

```

Direct SQL access remains available for complex analytical queries that join `nodes` and `edges` on `qualified_name` fields.

## Summary

- The `nodes` table stores 16 attributes per code entity, using `qualified_name` as a unique natural key and `kind` to discriminate between files, classes, functions, types, and tests.
- The `edges` table captures directed relationships with confidence scoring, supporting seven index-accelerated relationship types including `CALLS`, `IMPORTS_FROM`, and `INHERITS`.
- Seven strategic indexes across both tables optimize file-path filtering and bidirectional graph traversal.
- Schema initialization and versioning are handled by [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py) and [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py), enabling safe incremental updates.

## Frequently Asked Questions

### Where is the SQLite schema defined in the code-review-graph repository?

The schema is defined in the `_SCHEMA_SQL` string constant within [`code_review_graph/graph.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/graph.py), specifically between lines 42 and 73. This string contains the `CREATE TABLE` statements for the `nodes` and `edges` tables along with associated indexes.

### What types of relationships can be stored in the `edges` table?

The `kind` column accepts relationship types including `CALLS`, `IMPORTS_FROM`, `INHERITS`, `REFERENCES`, `CONTAINS`, `TESTED_BY`, and `DEPENDS_ON`. These values enable precise semantic modeling of code dependencies and hierarchies.

### How does code-review-graph handle schema migrations?

Migration logic is implemented in [`code_review_graph/migrations.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/migrations.py), which tracks the current schema version in a dedicated `metadata` table. The system applies incremental schema changes automatically when opening a database file created by an older version of the tool.

### Can I query the database directly without using the GraphStore API?

Yes, the database is a standard SQLite 3 file with properly indexed tables. You can execute direct SQL queries against the `nodes` and `edges` tables using the SQLite command-line tool or any compatible database driver, joining on `qualified_name` fields to reconstruct graph paths.