How DrawDB Generates Diagrams from AI Prompts: A Complete Technical Breakdown
DrawDB converts natural language or SQL prompts into interactive database diagrams through a four-stage pipeline: extension‑based AI request, JSON normalization, automatic table layout, and state integration.
DrawDB's AI-powered import feature lets you describe a database schema in plain English—or paste raw SQL—and instantly receive a fully-rendered, editable diagram. This article examines the exact code path that transforms your prompt into structured diagram state, based on the drawdb-io/drawdb source code.
The Four-Stage AI Import Pipeline
Stage 1: Initiating the AI Request
The journey begins in src/components/EditorHeader/Modal/Modal.jsx. When a user clicks Import with AI, the modal invokes importSourceWithAi:
// Modal.jsx lines 92-104
const importSourceWithAi = async () => {
setLoading(true);
try {
const diagram = await importSqlWithAi({
sql: importSource.src,
database: database === DB.GENERIC ? importDb : database,
allowedTypes: allowedTypesFor(database),
});
// ...normalization and state application
} finally {
setLoading(false);
}
};
This function delegates the actual AI call to importSqlWithAi, an extension hook provided by ExtensionsContext. The hook packages three critical pieces of information:
sql— the raw prompt or SQL textdatabase— the target database engine (PostgreSQL, MySQL, etc., or generic)allowedTypes— valid column types for that engine, drawn fromdbToTypes
The extension sends this payload to an external AI service (e.g., OpenAI), which returns a JSON diagram description containing tables, fields, relationships, enums, and custom types.
Stage 2: Normalizing the AI Response
Once the AI service responds, the raw JSON flows into normalizeAiDiagram in src/utils/importAiDiagram.js (lines 58-118). This function hardens the AI output into a valid internal diagram structure:
// importAiDiagram.js
export function normalizeAiDiagram(raw, database) {
// 1. Validate presence of tables
if (!raw.tables || raw.tables.length === 0) {
throw new Error("AI response contains no tables");
}
const warnings = [];
const typeMap = dbToTypes[database];
// 2. Resolve column types against database-specific type map
raw.tables.forEach(table => {
table.fields = table.fields.map(field => ({
...field,
type: resolveType(field.type, typeMap, warnings)
}));
});
// 3. Filter invalid relationships
const validRelationships = raw.relationships?.filter(r => {
const valid = relationshipPointsToValidColumns(r, raw.tables);
if (!valid) warnings.push(`Relationship ${r.name} references missing columns`);
return valid;
}) || [];
// 4. Construct diagram object
const diagram = {
tables: raw.tables,
relationships: validRelationships,
enums: raw.enums || [],
customTypes: raw.customTypes || [],
};
// 5. Validate final structure and compute layout
jsonDiagramIsValid(diagram);
arrangeTables(diagram);
return { diagram, warnings };
}
Three key operations happen here:
-
Type resolution via
resolveType: Maps AI-generated type strings to valid database types, handling aliases fromTYPE_ALIASES, user-defined enums, and falling back toFALLBACK_TYPESfor unrecognized entries. -
Relationship filtering: Verifies that every relationship endpoint points to actual table columns, collecting warnings for any orphans.
-
Schema validation:
jsonDiagramIsValidensures the diagram conforms to DrawDB's internal schema before layout computation.
Stage 3: Automatic Table Layout
After normalization, arrangeTables (imported from src/utils/arrangeTables.js) calculates an initial visual arrangement. This prevents overlapping tables and provides a sensible starting point for the diagram. The layout algorithm considers table dimensions and applies a force-directed or grid-based positioning strategy—details vary by DrawDB version, but the goal is always instant visual coherence without manual positioning.
Stage 4: State Integration
The normalized diagram returns to Modal.jsx, where applyImportedDiagram (lines 63-85) merges it into the application's React state:
// Modal.jsx
const applyImportedDiagram = (diagram) => {
setTables(diagram.tables);
setRelationships(diagram.relationships);
setEnums(diagram.enums || []);
setCustomType(diagram.customTypes || []);
setTypes(diagram.types || []);
setNotedef(diagram.notes || []);
setAreas(diagram.areas || []);
setUndoStack([]);
setRedoStack([]);
saveDiagram();
};
This operation:
- Replaces all current diagram entities with AI-generated ones
- Clears undo/redo history (the import is treated as a fresh start)
- Persists the result via
saveDiagram()
If normalizeAiDiagram returned warnings, the modal displays them via toast notification before closing.
Key Data Structures and Configuration
Type Resolution Pipeline
The resolveType function (in importAiDiagram.js) implements a priority-based lookup:
- Direct match in
dbToTypes[database] - Alias resolution through
TYPE_ALIASES(e.g., "string" → "VARCHAR") - User-defined enum/type matching
- Fallback types for unrecognized entries
This ensures that even imprecise AI type descriptions produce valid, database-specific column definitions.
Database-Specific Type Maps
src/data/datatypes.js exports dbToTypes, a comprehensive mapping for every supported engine:
// datatypes.js (conceptual)
export const dbToTypes = {
[DB.POSTGRESQL]: { "VARCHAR": {...}, "INTEGER": {...}, ... },
[DB.MYSQL]: { "VARCHAR": {...}, "INT": {...}, ... },
// ...other engines
};
The allowedTypesFor(database) helper extracts just the type names for the AI prompt context, constraining the model's output to valid options.
Comparing AI Import to Other Import Methods
DrawDB offers multiple import paths. Here's how AI generation differs:
| Method | Input | Processing | Best For |
|---|---|---|---|
| AI Import | Natural language or SQL | External AI service + normalization | Rapid prototyping, complex schemas described verbally |
| SQL Import | Valid SQL DDL | Parser-based, no external service | Existing database scripts, precise control |
| JSON Import | DrawDB export format | Direct validation only | Backup restoration, cross-workspace transfer |
The AI path trades determinism for convenience—the normalization layer in importAiDiagram.js exists specifically to recover from AI hallucinations or imprecise type names.
Error Handling and Edge Cases
The pipeline includes several safeguards:
- Empty table detection: Throws immediately if AI returns no tables
- Type fallback: Never fails on unrecognized types; warns and substitutes
- Relationship orphaning: Silently drops broken relationships with warnings
- Schema validation: Final
jsonDiagramIsValidcheck prevents corrupt state
These layers mean the AI import rarely fails completely—instead, it degrades gracefully with actionable warnings.
Summary
- Trigger:
importSourceWithAiinModal.jsxinitiates the flow viaimportSqlWithAi - AI Request: Extension hook sends prompt + database context to external service
- Normalization:
normalizeAiDiagramvalidates, resolves types, filters relationships, and runsarrangeTables - Integration:
applyImportedDiagramatomically replaces diagram state and resets history - Resilience: Multiple fallback layers ensure usable output even from imperfect AI responses
Frequently Asked Questions
What AI service does DrawDB use for diagram generation?
DrawDB delegates AI requests to external services through its extension system. The core repository provides the importSqlWithAi hook interface in ExtensionsContext, but the actual implementation—whether OpenAI, Anthropic, or another provider—is supplied by the deployed extension. This architecture keeps the open-source core provider-agnostic.
Can I use AI import with any database type?
Yes. The allowedTypesFor(database) function dynamically constrains the AI's output to valid types for your selected engine. If you select Generic mode, the modal prompts you to choose a specific database first, ensuring type resolution succeeds in normalizeAiDiagram.
What happens if the AI generates invalid SQL types?
The resolveType function in importAiDiagram.js implements a three-tier fallback: exact match, alias lookup, then FALLBACK_TYPES substitution. You'll receive a warning toast describing any replacements, but the import completes with safe defaults rather than failing.
How does DrawDB prevent overlapping tables in AI-generated diagrams?
After normalization, arrangeTables from src/utils/arrangeTables.js computes non-overlapping positions before state integration. The algorithm runs server-side in the normalization phase, so users see a coherent layout immediately without manual adjustment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →