# How DrawDB Imports SQL Schemas from Different Database Engines: A Deep Dive into the Open-Source Pipeline

> Discover how DrawDB imports SQL schemas from MySQL PostgreSQL SQLite and more. Explore its open source pipeline using a modular SQL AST parser and database specific transformers.

- Repository: [drawDB/drawdb](https://github.com/drawdb-io/drawdb)
- Tags: deep-dive
- Published: 2026-08-14

---

**DrawDB uses a modular SQL-to-AST parser combined with database-specific transformers to convert DDL from MySQL, PostgreSQL, SQLite, and other engines into its internal diagram model.**

The **drawdb-io/drawdb** repository implements a flexible import pipeline that transforms raw SQL schema definitions into interactive visual diagrams. This article explains how the codebase handles schema parsing across multiple database systems while maintaining type fidelity and producing readable auto-arranged layouts.

---

## Overview of the SQL Import Pipeline

DrawDB's import system follows a six-stage pipeline. Each stage isolates a specific concern, making the architecture extensible for new database engines.

| Stage | Purpose | Key File |
|-------|---------|----------|
| **Parse SQL to AST** | Convert raw DDL into a language-agnostic syntax tree | `sql-ddl-parser` (npm dependency) |
| **Route to Converter** | Select database-specific transformer | [`src/utils/importSQL/index.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/index.js) |
| **Transform to Internal Model** | Walk AST and build diagram objects | `src/utils/importSQL/<engine>.js` |
| **Normalize Data Types** | Map native types to generic DrawDB types | [`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js) |
| **Auto-Layout Tables** | Calculate initial canvas positions | [`src/utils/arrangeTables.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/arrangeTables.js) |
| **Render Diagram** | Update React state and paint SVG | [`src/context/DiagramContext.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/context/DiagramContext.jsx) |

The pipeline accepts either file drops or pasted DDL text, processing both through identical code paths.

---

## Stage 1: SQL Parsing with sql-ddl-parser

DrawDB delegates initial parsing to the **`sql-ddl-parser`** library. This open-source package handles lexical analysis and produces a normalized **AST** (abstract syntax tree) regardless of source database dialect.

The parser accepts CREATE TABLE statements with constraints, indexes, and foreign keys. It abstracts away syntactic differences—so `AUTO_INCREMENT` (MySQL), `SERIAL` (PostgreSQL), and `IDENTITY` (MSSQL) all become comparable AST nodes before database-specific interpretation.

---

## Stage 2: Database-Specific AST Transformation

The central dispatcher `importSQL` in [`src/utils/importSQL/index.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/index.js) receives the AST and routes it to the appropriate converter. Each supported database has a dedicated module:

- **`fromMySQL`** — [`src/utils/importSQL/mysql.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/mysql.js)
- **`fromPostgres`** — [`src/utils/importSQL/postgres.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/postgres.js)
- **`fromSQLite`** — [`src/utils/importSQL/sqlite.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/sqlite.js)
- **`fromMSSQL`** — [`src/utils/importSQL/mssql.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/mssql.js)
- **`fromMariaDB`** — [`src/utils/importSQL/mariadb.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/mariadb.js)
- **`fromOracleSQL`** — [`src/utils/importSQL/oraclesql.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/oraclesql.js)

Each `from<Engine>` function implements the same interface: it traverses the AST, extracts structural elements, and returns DrawDB-native objects.

### MySQL-Specific Handling

```javascript
// src/utils/importSQL/mysql.js
// Simplified excerpt showing AUTO_INCREMENT detection

function fromMySQL(ast, diagram) {
  ast.forEach(stmt => {
    if (stmt.type === "create") {
      const table = {
        name: stmt.table.name,
        columns: stmt.columns.map(col => ({
          name: col.name,
          type: dbToTypes(col.datatype, DB.MYSQL),
          nullable: col.nullable !== false,
          primary: col.primary_key || false,
          autoIncrement: col.auto_increment || false
        }))
      };
      diagram.tables.push(table);
    }
  });
}

```

Key MySQL constructs handled: `ENUM` types, `AUTO_INCREMENT`, `UNSIGNED` integers, and engine clauses.

### PostgreSQL-Specific Handling

The PostgreSQL converter in [`src/utils/importSQL/postgres.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/postgres.js) handles:

- **`SERIAL`** and `BIGSERIAL` pseudo-types (converted to auto-incrementing integers)
- **Array types** (`INTEGER[]`, `TEXT[]`)
- **`JSONB`** and `JSON` column types
- **`GENERATED ALWAYS AS`** computed columns

### SQLite-Specific Handling

`fromSQLite` in [`src/utils/importSQL/sqlite.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/sqlite.js) accommodates SQLite's minimal DDL:

- Implicit `INTEGER PRIMARY KEY` as `ROWID` alias
- `WITHOUT ROWID` tables
- Limited foreign key syntax without named constraints
- Type affinity rules (e.g., `VARCHAR(50)` affinity-matches to `TEXT`)

---

## Stage 3: Type Normalization with dbToTypes

Every converter calls **`dbToTypes`** from [`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js) to translate native column types into DrawDB's generic type system.

| Native Type | Database | DrawDB Generic Type |
|-------------|----------|---------------------|
| `VARCHAR2(100)` | Oracle | `STRING` |
| `NVARCHAR` | MSSQL | `STRING` |
| `SERIAL` | PostgreSQL | `INTEGER` (autoIncrement=true) |
| `NUMBER(10,2)` | Oracle | `DECIMAL` |
| `BOOLEAN` | PostgreSQL | `BOOLEAN` |
| `TINYINT(1)` | MySQL | `BOOLEAN` |

This normalization ensures that diagrams remain portable and that export to different target databases produces valid DDL.

---

## Stage 4: Building the Internal Diagram Model

Converters instantiate three core object types defined in [`src/data/db.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/db.js):

- **`Table`** — Container with name, comment, and positioning metadata
- **`Column`** — Typed field with constraints, default values, and display options
- **`Relationship`** — Foreign key links with cardinality (`1:1`, `1:N`, `N:M`)

The populated `db` store becomes the single source of truth for React's state management.

---

## Stage 5: Auto-Arranging the Canvas Layout

After model construction, **`arrangeTables`** in [`src/utils/arrangeTables.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/arrangeTables.js) computes initial positions.

The algorithm:

1. Groups tables by connected components (isolated subgraphs)
2. Applies force-directed placement to minimize edge crossings
3. Respects minimum spacing constraints for readability
4. Centers the viewport on the resulting bounding box

Users can manually reposition tables after import; the layout is non-destructive.

---

## Stage 6: Rendering via React Contexts

The **`DiagramContext`** in [`src/context/DiagramContext.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/context/DiagramContext.jsx) subscribes to the `db` store and triggers re-renders. Components in `src/components/Canvas/` paint:

- **SVG rectangles** for tables with header and field sections
- **Bezier curves** for relationship lines
- **Cardinality indicators** (crow's foot notation)

---

## Programmatic Usage Example

Import a MySQL schema without the UI:

```javascript
import { importSQL } from "./src/utils/importSQL";
import { DB } from "./src/data/constants";
import { sqlParser } from "sql-ddl-parser";

const ddl = `
CREATE TABLE departments (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE employees (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  dept_id INT,
  FOREIGN KEY (dept_id) REFERENCES departments(id)
);
`;

const ast = sqlParser(ddl);
const diagram = importSQL(ast, DB.MYSQL, DB.GENERIC);

// diagram.tables.length === 2
// diagram.relationships contains the FK link

```

---

## Adding Support for New Database Engines

The modular architecture enables straightforward extension:

1. Create [`src/utils/importSQL/newengine.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/newengine.js)
2. Export a `fromNewEngine(ast, diagram)` function
3. Register the route in [`src/utils/importSQL/index.js`](https://github.com/drawdb-io/drawdb/blob/main/src/utils/importSQL/index.js)
4. Add type mappings to [`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js)

The existing pipeline handles normalization, layout, and rendering automatically.

---

## Summary

- **DrawDB imports SQL schemas** using the `sql-ddl-parser` library to produce ASTs, then routes to database-specific converters.
- **Six dedicated modules** ([`mysql.js`](https://github.com/drawdb-io/drawdb/blob/main/mysql.js), [`postgres.js`](https://github.com/drawdb-io/drawdb/blob/main/postgres.js), [`sqlite.js`](https://github.com/drawdb-io/drawdb/blob/main/sqlite.js), [`mssql.js`](https://github.com/drawdb-io/drawdb/blob/main/mssql.js), [`mariadb.js`](https://github.com/drawdb-io/drawdb/blob/main/mariadb.js), [`oraclesql.js`](https://github.com/drawdb-io/drawdb/blob/main/oraclesql.js)) handle dialect-specific semantics.
- **Type normalization** via `dbToTypes` ensures cross-database portability.
- **Auto-layout** via [`arrangeTables.js`](https://github.com/drawdb-io/drawdb/blob/main/arrangeTables.js) produces readable initial diagrams.
- **Extensible architecture** requires only a new converter file to add database support.

---

## Frequently Asked Questions

### What databases does DrawDB support for SQL schema import?

DrawDB supports MySQL, PostgreSQL, SQLite, Microsoft SQL Server, MariaDB, and Oracle SQL. Each has a dedicated transformer module in `src/utils/importSQL/` that handles dialect-specific syntax like `SERIAL`, `IDENTITY`, or `VARCHAR2`.

### Can DrawDB import schemas from SQL dump files?

Yes. The parser accepts any text containing valid DDL CREATE statements. Users can paste dump contents directly or drag-and-drop `.sql` files. The UI extracts the text and passes it through the same `importSQL` pipeline.

### How does DrawDB handle database-specific data types?

Each converter calls `dbToTypes()` from [`src/data/datatypes.js`](https://github.com/drawdb-io/drawdb/blob/main/src/data/datatypes.js), which maps native types (e.g., PostgreSQL `JSONB`, Oracle `NUMBER`) to DrawDB's generic type system. This normalization allows diagrams to be exported to different target databases later.

### Is the imported diagram layout editable?

Yes. The `arrangeTables` function computes only an initial layout. Users can drag tables, resize them, and manually route relationship lines. The auto-layout is non-destructive and can be re-triggered from the UI if desired.