This system ingests SAP Order-to-Cash dataset, constructs a graph of interconnected entities, visualizes it, and allows natural language queries.
The system follows a modular architecture with clear separation of concerns:
- Data Layer: JSONL file ingestion and SQLite database for efficient querying
- Graph Layer: NetworkX-based graph construction with entity relationships
- Visualization Layer: PyVis interactive graph rendering
- Query Layer: LLM-powered natural language to SQL translation
- UI Layer: Streamlit web interface with tabbed navigation
app.py: Main Streamlit applicationsap-order-to-cash-dataset/: Raw SAP data filessap_data.db: SQLite database for queriesgraph.html: Generated graph visualization
Why SQLite?
- Lightweight: No server required, embedded database
- Read-optimized: Perfect for analytical queries on static datasets
- Python-native: Excellent pandas integration via
to_sql()andread_sql_query() - ACID compliance: Reliable transactions for data integrity
- File-based: Easy deployment and backup
Data Processing:
- JSONL files loaded into pandas DataFrames
- Dict columns converted to JSON strings for SQLite compatibility
- Tables created with
df.to_sql(if_exists='replace') - Foreign key relationships preserved through JOIN queries
The system uses a hybrid approach combining LLM power with rule-based fallbacks:
You are a SQL expert. Given the following database schema:
{table1}: {columns}
{table2}: {columns}
...
Translate the following natural language question into a SQL query. The database is SQLite.
Question: {user_question}
Return only the SQL query, no explanation.
Benefits:
- Provides full context of available tables and columns
- Ensures generated SQL is syntactically correct
- Leverages LLM's understanding of SQL patterns
For common query patterns when API is unavailable:
- Aggregation queries: "highest number of X" →
SELECT col, COUNT(*) FROM table GROUP BY col ORDER BY count DESC - Flow tracing: Complex JOINs for order-to-cash pipeline
- List queries: "list all customers" →
SELECT * FROM business_partners - Integrity checks: UNION queries for broken flows
Why Hybrid?
- Reliability: Works without internet/API dependency
- Cost-effective: Reduces API calls for predictable queries
- Fast: Rule-based responses are instant
- Comprehensive: Covers most user needs
The system implements multiple layers of guardrails to ensure safe, relevant responses:
dataset_keywords = ['order', 'delivery', 'billing', 'payment', 'customer', 'product', 'invoice', 'journal', 'sales', 'material', 'plant', 'partner']
if not any(kw in question.lower() for kw in dataset_keywords):
return "This system is designed to answer questions related to the provided dataset only."Purpose: Restricts queries to SAP Order-to-Cash domain only.
- LLM prompted with exact table/column names
- No access to external data or general knowledge
- SQL generation limited to provided schema
- Generated SQL executed against known database
- Error handling for malformed queries
- Fallback to safe default queries
- All answers based on actual dataset queries
- No hallucinated information
- Transparent SQL display for user verification
-
Install dependencies:
pip install pandas networkx pyvis streamlit openai -
Set your OpenAI API key in
app.py(replace "your-api-key-here") -
Run:
python -m streamlit run app.py
-
Graph Construction: Nodes for entities (Sales Orders, Deliveries, Billings, etc.), edges for relationships.
-
Visualization: Interactive graph using PyVis.
-
Query Interface: Natural language to SQL translation using OpenAI GPT, with fallbacks.
-
Guardrails: Restricts to dataset-related queries.
-
"Which products are associated with the highest number of billing documents?"
-
"Trace the full flow of billing document 90504248"
-
"Identify sales orders that have broken or incomplete flows"