DuckDB LLM UDF
Query your database in plain English—no SQL required. DuckDB LLM UDF translates natural language to SQL using large language models like OpenAI GPT-4 and Anthropic Claude.
✨ Overview
DuckDB LLM UDF bridges the gap between natural language and database queries. It's perfect for:
- Data analysts who need quick answers without writing complex SQL
- Application developers looking to add natural language query capabilities
- SQL learners who want to see how their questions translate to SQL
- DuckDB users who want to leverage the power of modern LLMs
This Python-based extension creates User-Defined Functions (UDFs) that let you query your database in plain English:
- 📚 Schema Analysis: Automatically extracts your database schema metadata
- 🤖 LLM Integration: Sends properly formatted prompts to OpenAI or Anthropic
- 🔍 SQL Generation: Converts natural language to accurate SQL
- ✅ Safety First: Asks for confirmation before executing any generated SQL
- 📊 Results Delivery: Returns query results in standard DuckDB format
🚀 Demo
Here's a screenshot of DuckDB LLM UDF in action:
🚀 Installation
Core features only:
pip install duckdb-llm-udf
With OpenAI support:
pip install duckdb-llm-udf[openai]
With Anthropic support:
pip install duckdb-llm-udf[anthropic]
With all providers:
pip install duckdb-llm-udf[all]
Or install from source:
git clone https://github.com/SQLxAI/duckdb-llm-udf.git
cd duckdb_llm_udf
pip install -e .
Dependencies
The package will automatically install the required dependencies:
- DuckDB ≥ 0.8.0
- python-dotenv ≥ 0.19.0 (for .env file support)
- numpy ≥ 1.21.0 (required for DuckDB UDFs)
Optional dependencies (installed with extras):
- OpenAI: for GPT model integration
- Anthropic: for Claude model integration
To use OpenAI or Anthropic, install the corresponding extra as shown above.
🔍 Usage
Python API
import os
from dotenv import load_dotenv
import duckdb
from duckdb_llm_udf import register_llm_functions
# Sample database creation for demonstration
def create_sample_database(conn):
...
# Usage example
if __name__ == "__main__":
# Load .env file from current working directory
load_dotenv()
conn = duckdb.connect()
register_llm_functions(conn)
create_sample_database(conn)
# Set API key in DuckDB (required for LLM queries)
api_key = os.environ.get('OPENAI_API_KEY', '')
if not api_key:
print("Warning: No OpenAI API key found. Please set the OPENAI_API_KEY environment variable.")
print("Alternatively, you can set it with: conn.execute(\"SELECT llm_configure('api_key', 'your-api-key')\")")
else:
conn.execute(f"SELECT llm_configure('api_key', '{api_key}')")
# Ask a question in natural language
query = "Show me the top 5 customers by total order amount"
# Option 1: Generate SQL without executing (for review)
sql = conn.execute(f"SELECT ask_llm('{query}', 'execute', 'false')").fetchone()[0]
print(f"Generated SQL:\n{sql}")
# Option 2: Execute directly with user confirmation
result = conn.execute(f"SELECT ask_llm('{query}')").fetchall()
print(result)
# Direct Python function usage
from duckdb_llm_udf.llm_udf import ask_llm
result = conn.execute(f"SELECT ask_llm('{query}')").fetchall()
print(result)
# Direct Python function usage
from duckdb_llm_udf.llm_udf import ask_llm
# Generate SQL without executing
sql = ask_llm(query, conn, execute=False)
print(f"Generated SQL:\n{sql}")
# Execute with confirmation
results = ask_llm(query, conn)
print(results)
⚙️ Configuration
You can configure DuckDB LLM UDF in three ways:
1. Environment Variables
# API Keys (required for corresponding provider)
OPENAI_API_KEY=sk-your-openai-key-here
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key-here
# Configuration (all optional)
LLM_PROVIDER=openai # Default: "openai", Alternatives: "anthropic"
LLM_MODEL=gpt-4o # Default: "gpt-3.5-turbo" or "claude-3-sonnet-20240229"
LLM_TEMPERATURE=0.7 # Controls randomness (0.0-1.0)
LLM_MAX_TOKENS=4096 # Maximum tokens for LLM response
2. .env File (recommended for security)
Create a .env file in your project with the same variables as above:
# API Keys
OPENAI_API_KEY=sk-your-openai-key-here
# Configuration
LLM_PROVIDER=openai
LLM_MODEL=gpt-4o
LLM_TEMPERATURE=0.3
Variables will automatically load when the package is imported. See examples/.env.example for a template.
3. Runtime Configuration
Python interface:
conn.execute("SELECT llm_configure('api_key', 'your-api-key')")
conn.execute("SELECT llm_configure('model', 'gpt-4-turbo')")
🧪 Examples
The examples/ directory contains ready-to-use examples:
basic_usage.py- Core functionality demonstrationdotenv_usage.py- Using environment variables with a .env filetest_extraction.py- Test schema extraction without LLM API calls
Example Questions
Here are some example questions you can ask your database:
- "Show me the top 5 customers by total order amount"
- "How many orders were placed in each month of 2023?"
- "What's the average order value by product category?"
- "Find customers who haven't made a purchase in the last 30 days"
- "What product has generated the most revenue?"
🔧 How It Works
Security & Safety
- Use
execute=Falseto preview generated SQL before running it. - Always validate output SQL in production contexts to prevent malformed or dangerous queries.
- LLM prompts are sent to the providers you configure (OpenAI/Anthropic).
-
Schema Analysis: When you call
ask_llm(), the function extracts your database schema metadata (tables, columns, types, foreign keys, etc.) -
Prompt Engineering: Your natural language question is combined with the schema into a carefully crafted prompt that helps the LLM understand the context
-
LLM Query: The prompt is sent to the configured LLM (OpenAI or Anthropic) with instructions to generate valid SQL
-
SQL Generation: The LLM produces SQL based on your schema and question
-
Safety Check: The generated SQL is presented to you for review and confirmation
-
Execution: If approved, the SQL is executed and the results are returned in standard DuckDB format
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
👥 Contributing
Contributions are welcome and appreciated! Here's how you can help:
- 🐛 Report bugs by opening an issue
- 💡 Suggest features or improvements
- 🧪 Improve tests or add new test cases
- 📚 Improve documentation to make it clearer or more complete
- 🧑💻 Submit pull requests with bug fixes or new features
Please see CONTRIBUTING.md for more details.
🙏 Credits
This project was built with:
- DuckDB - The in-process SQL OLAP database management system
- OpenAI API - For GPT model integration
- Anthropic API - For Claude model integration
📨 Contact
If you have any questions or need help, please open an issue on GitHub.
Metadata
Release files for duckdb-llm-udf 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| duckdb_llm_udf-0.1.4.tar.gz | 19.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| duckdb_llm_udf-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 30.6 kB
Release files / duckdb_llm_udf-0.1.4.tar.gz
| Download URL | duckdb_llm_udf-0.1.4.tar.gz |
|---|---|
| Size | 19.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14202a030a11a4120c38f4f51bf67090635ba6b4642c56eca0d95928cb7f27ba
|
|
BLAKE2b-256 checksum How to use checksums |
002215c973f651fa1ed337e032eb98ad77d9051f96345ef48444f9b962d96046
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|
Release files / duckdb_llm_udf-0.1.4-py3-none-any.whl
| Download URL | duckdb_llm_udf-0.1.4-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
263dbbef81fb7381d5a6e7d924fd1932c938cdd0d03f8f284d0b395423388ab3
|
|
BLAKE2b-256 checksum How to use checksums |
b75a724e2cbd41c78412221d5c717ec6eb92b4f4975a429e170740275d457f1a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.3
|
Security for duckdb-llm-udf 0.1.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.