top of page

Chat with Your DataBase Without the Drama


If you’ve ever written a gnarly SQL query with multiple joins, filters, and window functions in a tool like DBeaver, you’ve probably hit this point: “I finally got the query right. Now I want to explore this result in lots of different ways… without rewriting SQL every time or accidentally breaking something in prod.”


There’s a great pattern for this:

1.      Use DBeaver (or any SQL IDE) to build one carefully-reviewed, complex query against your database.

2.     Export the result to CSV.

3.     Load that CSV into DuckDB.

4.     Use natural language with Ollama + PremSQL to generate SQL and analyze the data safely, locally, and quickly.


This keeps the risky parts (joins, permissions, performance) in your controlled SQL IDE, and turns the result into a flat, read-only dataset for exploration.

Privacy? The entire stack described here can run on an air-gapped laptop, with no network connection.


Why DuckDB?  DuckDB is an in-process analytical database designed for Online Analytical Processing (OLAP). Unlike traditional databases that run as servers, DuckDB runs directly within an application, optimized for analytics rather than transactions.

Key characteristics of DuckDB include:

  • Columnar storage for efficient analytical queries

  • Vectorized query execution for high performance

  • Full SQL support with advanced analytical functions

  • Seamless integration with Python, and other data tools

  • Ability to query large datasets stored in files like CSV

 

Here is a practical guide to why this is useful and how a novice user can build it:


Why Export to CSV and Analyze Locally?

1. Safety and Isolation

·       You’re not pointing an LLM directly at your production database.

·       The CSV is read-only, detached from your live system.

·       If a generated SQL query is wrong or inefficient, it only affects the local DuckDB file, not prod.

2. Simpler Schema = Less Hallucination

·       A few CSV files form flat tables: columns are explicit, no foreign keys or complex relationships.

·       The model doesn’t need to “guess” join paths; it just works with columns it can see.

·       Reduces “creative” but wrong SQL (joins to non-existent tables, weird schemas).

3. Performance

·       DuckDB + local CSVs is extremely fast for analytical queries.

·       With PremSQL running on GPU via Ollama, you get 2–6 second query generation plus sub-second execution.

·       You can iterate quickly: ask a question >>>see results >>>refine >>>repeat.

4. Clear Responsibility Boundary

·       You are responsible for the initial complex query and the business logic behind it.

·       The LLM is responsible only for alternative slices, filters, aggregations, and summaries on the resulting data.


High-Level Architecture

Think of the pipeline as:

1.      Database (prod / staging)- Complex SQL with joins, filters, business rules- Executed and verified in DBeaver.

2.     CSV Export- Save result to analysis_dataset.csv.

3.     Local Analytics Sandbox

o   DuckDB loads analysis_dataset.csv as a table (dataset).

o   Python script uses Ollama + PremSQL to:

§  Accept natural language questions.

§  Generate SQL over dataset.

§  Run it in DuckDB.

§  Print results as a pretty table.

4.     User Interacts only with natural language, not SQL.


Step-by-Step: Instructions


Prerequisites

Basic familiarity with:

o   Running Python scripts

o   Installing tools with pip

o   Running commands in Terminal (macOS/Linux) or PowerShell/cmd (Windows)

o   Write and run SQL in DBeaver.


Step 1: Create Your “Master” Query in DBeaver

In DBeaver:

1.      Connect to your database (prod, staging, or a read-only replica).

2.     Write the full, complex SQL that:

o   Joins all relevant tables.

o   Applies business logic (filters, derived columns).

o   Produces a table-shaped result with the columns you care about.

3.     Test it:

o   Validate counts, sample rows, and edge cases.

o   Ensure performance is acceptable

Once you’re happy with it, export the result:

·       Right-click on the results grid >>>Export Data or similar.

·       Choose CSV.

·       Save as, for example: analysis_dataset.csv.

Now you have a frozen snapshot of your complex query output.


Step 2: Set Up Your Local Project

Create a folder, e.g.:

nl-sql-sandbox/nl_sql.py

analysis_csv/

analysis_dataset.csv

Move your exported CSV into analysis_csv/.


Step 3: Install Dependencies

From the nl-sql-sandbox directory:

pip install duckdb pandas llama-index-llms-ollama

Pull the PremSQL model into Ollama:

ollama pull anindya/prem1b-sql-ollama-fp116

This gives you:

·       duckdb: In-process OLAP database where you’ll query the CSV.

·       pandas: For nice tabular printing.

·       llama-index-llms-ollama: A simple Python wrapper to call Ollama from your script.

·       PremSQL model via Ollama: specialized for Text-to-SQL.


Step 4: The Minimal Python Script

Create nl_sql.py with this stripped-down, novice-friendly script:


Copy the contents of the doc file and create a text file with a .py extension


Step 5: Run It

python nl_sql.py

You’ll see:

·       A sample of your CSV loaded as dataset.

·       A prompt:

Ask about your dataset >>>

Now try:

·       show first 10 rows

·       sum of sales by region

·       average margin for each product category

·       top 10 customers by total revenue

The script will:

1.      Send your question + schema + examples to PremSQL via Ollama.

2.     Get back a SELECT query over dataset.

3.     Run it in DuckDB.

4.     Show the results as a nice table.


How This Uses the GPU

·       The heavy lifting (Text-to-SQL generation) happens inside Ollama, running the anindya/prem1b-sql-ollama-fp116model.

·       If Ollama is configured with GPU support and your GPU has enough VRAM, most of the model will run on GPU, making generation much faster than CPU-only.

·       The Python script itself doesn’t manage GPU; it just calls Ollama. Ollama decides CPU vs GPU.

You can confirm GPU usage with tools like nvidia-smi and ollama ps while queries are running.


Limitations

1.      Flat table

o   You’re querying the exported result, not the original multi-table schema.

o   Great for analysis; not for OLTP-type operations.

2.     No automatic refresh

o   If source data changes, you must re-run the complex query in DBeaver and re-export the CSV.

3.     Model isn’t perfect

o   It can still:

§  Misname columns

§  Misinterpret ambiguous questions

o   But with schema + examples + rules, errors are reduced significantly.


How to Use It Effectively (NL Prompting Tips)

·       Be explicit about metrics and grouping:

o   Good: total revenue by region for 2024

o   Better: sum of revenue grouped by region where year = 2024

·       Reference visible column names (if you know them):

o   average stdCost by category

o   count of rows where status = 'Closed'

·       Constrain the scope:

o   top 10 customers by total_sales

o   top 5 products by margin where margin > 0.2

·       Start simple, then iterate:

o   show first 10 rows

o   show all distinct regions

o   count rows where quantity > 0

·       Specify more rules in the query

o    If you notice an obvious error in the SQL generated, like a wrong table name, correct it in the next query using rules.

·       Have patience

o    Review the generated SQL queries, usually printed above the answer and refine as needed.


Recap

This is a powerful, safe, and privacy oriented pattern:

·       Do the dangerous work (joins, business logic) once in a trusted SQL IDE (DBeaver).

·       Freeze the result into a CSV snapshot.

·       Use DuckDB + Ollama + PremSQL, running mostly on GPU, to explore that data with natural language.

It’s a great way to give yourself (or non-SQL teammates) a “query copilot” without ever giving an LLM direct access to production, while keeping your data private.

Comments


bottom of page