# Structured2Graph

Structured2Graph migrates a relational database, MySQL or PostgreSQL, to Memgraph.
It reads the relational schema, proposes a graph model, lets you review and
change it, migrates the data and validates the result.

Structured2Graph can design the graph model in two ways:

- **Deterministic strategy:** Maps tables to nodes and foreign keys to
  relationships by rules.
- **LLM strategy:** An LLM reads the schema and proposes a model with
  meaningful labels and relationship types.

It runs in one of two modes:

- **Automatic mode:** Migrates without asking you anything.
- **Incremental mode:** Shows the graph model step by step, so you can review
  and change it before the migration.

You choose the strategy and the mode with command-line options or environment
variables. Structured2Graph validates the data before and after the migration and
reports the result.

## Supported databases

| Type | Supported options |
|------|-------------------|
| **Source databases** | PostgreSQL, MySQL |
| **Target database** | Memgraph |

## Prerequisites

You need a running PostgreSQL or MySQL database to migrate, and Memgraph
started with schema tracking enabled. To install Memgraph, see [Install
Memgraph](https://memgraph.com/docs/getting-started/install-memgraph). To start it in Docker with
schema tracking:

```bash
docker run -p 7687:7687 memgraph/memgraph --schema-info-enabled=true
```

> **Warning**
>
> Start Memgraph with `--schema-info-enabled=true`. Without it, Structured2Graph can't
> read the graph schema to validate the migration.

## Installation

Install Structured2Graph from PyPI. It needs Python 3.10 or later:

```bash
pip install structured2graph
```

This installs the `structured2graph` command, which runs Structured2Graph.

## Configuration

Structured2Graph reads its settings from environment variables: the source database
and Memgraph connections, and the API key for your LLM provider.

Create a `.env` file in the folder you run `structured2graph` from, with the
following variables:

```bash
# Source Database
SOURCE_DB_TYPE=postgresql  # or mysql

# PostgreSQL Configuration
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DATABASE=mydb
POSTGRES_USER=username
POSTGRES_PASSWORD=password
POSTGRES_SCHEMA=public

# MySQL Configuration (if using MySQL)
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DATABASE=mydb
MYSQL_USER=username
MYSQL_PASSWORD=password

# Target Memgraph Database
MEMGRAPH_URL=bolt://localhost:7687
MEMGRAPH_USERNAME=
MEMGRAPH_PASSWORD=
MEMGRAPH_DATABASE=memgraph

# LLM API Keys (for AI-powered features)
# Only provide the key for your chosen provider
OPENAI_API_KEY=sk-...          # For GPT models
# ANTHROPIC_API_KEY=sk-ant-...  # For Claude models
# GOOGLE_API_KEY=AI...          # For Gemini models

# Optional: Specify LLM model (defaults shown)
# LLM_MODEL=gpt-4o                # OpenAI default
# LLM_MODEL=claude-sonnet-5       # Anthropic default
# LLM_MODEL=gemini-2.0-flash-exp  # Google default
```

[`.env.example`](https://github.com/memgraph/ai-toolkit/blob/main/agents/sql2graph/.env.example)
in the AI Toolkit repository lists every variable, and you can copy it as a
starting point.

The migration defaults `SQL2MG_MODE`, `SQL2MG_STRATEGY`, `SQL2MG_META_POLICY`
and `SQL2MG_LOG_LEVEL` have no effect in `.env`, because `structured2graph`
reads them before it loads the file. Set them in your shell, or pass the
matching [command-line options](#command-line-options).

## Run a migration

You can run Structured2Graph in four ways, from fully automatic to fully reviewed.

### Automatic migration

Run in automatic mode with the deterministic strategy:

```bash
structured2graph --mode automatic --strategy deterministic
```

Without `--mode` and `--strategy`, `structured2graph` asks for both.

The agent will:
1. Validate your environment and database connections
2. Analyze the source database schema
3. Generate a complete graph model
4. Execute the migration
5. Validate the results

In automatic mode, Structured2Graph asks you nothing. The mode (`--mode` or
`SQL2MG_MODE`) sets how much you review, and the strategy (`--strategy` or
`SQL2MG_STRATEGY`) sets how the graph model is designed.

### Refinement with incremental mode

For more control, run in incremental mode to review and refine the model
step-by-step:

```bash
structured2graph --mode incremental
```

Incremental mode needs an LLM API key even with the deterministic strategy,
because it uses the LLM to apply the changes you describe.

The agent will:
1. Analyze the source database schema
2. Generate an initial graph model
3. Present each table's proposed transformation for review
4. Allow you to accept, skip, or modify each table's mapping
5. After reviewing all tables, optionally enter a refinement loop for final
   adjustments
6. Execute the migration
7. Validate the results

This is predictable and repeatable flow so you can iteratively improve the graph
model before migration. Each table is processed one at a time, and you have full
control over the transformations, the table will show you all the proposed
nodes, relationships, and properties for that table, and you can choose to
accept them as-is, skip the table entirely, or modify the mapping details.

### Interactive migration with LLM

Use LLM-powered modeling for AI driven design:

```bash
structured2graph --mode automatic --strategy llm
```

The agent auto-detects which LLM provider to use based on available API keys. In
this strategy, the agent will:
1. Analyze your SQL schema semantically using LLM
2. Generate an initial graph model with AI-optimized design
3. Execute the migration
4. Validate the results

Keep in mind that in this mode, the entire migration is still automatic and LLM
driven. 

### Incremental migration with review

Control each step of the transformation:

```bash
structured2graph --mode incremental --strategy llm
```

In incremental mode:
1. The AI generates a complete graph model for all tables
2. You review each table's mapping one at a time
3. Accept or modify individual table transformations
4. After processing all tables, optionally enter a refinement loop
5. Interactively adjust the entire model before final migration

In this mode the LLM is used to generate the initial model, but you have full
control to review and refine each table's mapping before migration. After each
modification, the LLM will try to regenerate based on your feedback and
validation errors to improve the model iteratively.

## CLI reference

### Command-line options

| Flag | Environment variable | Description | Default |
|------|---------------------|-------------|---------|
| `--mode` | `SQL2MG_MODE` | `automatic` or `incremental` | interactive prompt |
| `--strategy` | `SQL2MG_STRATEGY` | `deterministic` or `llm` | interactive prompt |
| `--provider` | `LLM_PROVIDER` | `openai`, `anthropic`, or `gemini` | auto-detect from API keys |
| `--model` | `LLM_MODEL` | Specific model name | provider default |
| `--meta-graph` | `SQL2MG_META_POLICY` | `auto`, `skip`, or `reset` | `auto` |
| `--log-level` | `SQL2MG_LOG_LEVEL` | `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG` or `NOTSET` | `INFO` |
| `--mapping PATH` | _(none)_ | Write a mapping JSON file at `PATH` instead of migrating, then open it for editing. An existing file opens directly. | none |
| `--connector NAME` | _(none)_ | Memgraph Zero connector name to set on every element of the mapping | the only registered connector |
| `--editor CMD` | `EDITOR` or `VISUAL` | Editor that opens the mapping file, such as `nano`, `vim` or `'code --wait'` | `EDITOR`, then `VISUAL`, then `vi` |

The mapping file is a Memgraph Zero graph definition over the SQL tables, which
you load with
[`CREATE GRAPH <name> FROM FILE '<path>'`](https://memgraph.com/docs/memgraph-zero/memgql/reference#graph-management-query-syntax).

### Usage examples

```bash
# Use specific Gemini model
structured2graph --strategy llm --provider gemini --model gemini-2.0-flash-exp

# Skip meta-graph comparison (treat as fresh migration)
structured2graph --meta-graph skip

# Enable debug logging
structured2graph --log-level DEBUG

# Fully configured non-interactive run
structured2graph \
  --mode automatic \
  --strategy deterministic \
  --meta-graph reset \
  --log-level INFO
```

## LLM provider support

| Provider | API key | Default model |
|----------|---------|---------------|
| OpenAI | `OPENAI_API_KEY` | `gpt-4o` |
| Anthropic | `ANTHROPIC_API_KEY` | `claude-sonnet-5` |
| Google | `GOOGLE_API_KEY` | `gemini-2.0-flash-exp` |

### Provider selection

The agent selects the provider in this order:

1. The `--provider` option.
2. The `LLM_PROVIDER` environment variable.
3. The first API key it finds: `OPENAI_API_KEY`, then `ANTHROPIC_API_KEY`, then
   `GOOGLE_API_KEY`.

Override with `--provider` flag:

```bash
# Force Anthropic even if OpenAI key exists
structured2graph --strategy llm --provider anthropic
```

### Model selection

Each provider uses the default model in the table above. Override it with
`--model` or the `LLM_MODEL` environment variable:

```bash
# Use a smaller OpenAI model
structured2graph --mode automatic --strategy llm --model gpt-4o-mini

# Or via the environment variable
export LLM_MODEL=claude-opus-5-5
structured2graph --mode automatic --strategy llm --provider anthropic
```
