Database storage
Persist, query, and retrieve your analysis results with any database.
Overview
Reveilio can route analysis results to a database so you can store, query, and retrieve them later. Four backends are supported out of the box:
SQLite
Zero-config file-based storage. No server needed. Ships with Python.
PostgreSQL
Production-grade relational database with JSONB support.
MySQL
Widely deployed relational database with JSON column support.
MongoDB
Document-oriented database — a natural fit for nested analysis data.
Installation
SQLite works out of the box (it is part of the Python standard library). For other backends, install the relevant extra:
# PostgreSQL
pip install reveilio[postgresql]
# MySQL
pip install reveilio[mysql]
# MongoDB
pip install reveilio[mongodb]
# All database backends at once
pip install reveilio[all-db]
Connecting to a database
Call reveilio.connect_db() once at program start to establish a
connection. All subsequent export_* and import_* calls
use this connection automatically.
SQLite
The simplest option — no server, no credentials, just a file path.
import reveilio
reveilio.connect_db(
"sqlite",
filepath="my_analyses.db", # creates file if it doesn't exist
)
If you omit filepath, it defaults to reveilio.db in the current directory.
PostgreSQL
reveilio.connect_db(
"postgresql",
host="localhost",
port=5432,
database="recruitment",
username="admin",
password="secret",
)
Environment fallbacks: REVEILIO_DB_HOST, REVEILIO_DB_PORT,
REVEILIO_DB_NAME, REVEILIO_DB_USER, REVEILIO_DB_PASSWORD.
MySQL
reveilio.connect_db(
"mysql",
host="db.example.com",
port=3306,
database="hiring",
username="root",
password="secret",
)
MongoDB
reveilio.connect_db(
"mongodb",
host="localhost",
port=27017,
database="reveilio",
username="admin", # optional
password="secret", # optional
)
Connection string override
For any backend, you can pass a full connection string instead of individual parameters:
reveilio.connect_db(
"postgresql",
connection_string="postgresql://user:pass@host:5432/mydb",
)
Environment variables
Every connection parameter can be set via environment variables. This is useful for production deployments where credentials should not be in code:
| Variable | Description | Default |
|---|---|---|
REVEILIO_DB_BACKEND | Database backend | sqlite |
REVEILIO_DB_HOST | Database host | localhost |
REVEILIO_DB_PORT | Database port | Backend default |
REVEILIO_DB_NAME | Database name | reveilio |
REVEILIO_DB_USER | Username | Backend default |
REVEILIO_DB_PASSWORD | Password | — |
REVEILIO_DB_FILEPATH | SQLite file path | reveilio.db |
REVEILIO_DB_URL | Full connection string | — |
REVEILIO_DB_TABLE | Table / collection name | reveilio_analyses |
Exporting results to the database
After running an analysis, export the results to the database:
Single result
# Analyze and export
result = reveilio.analyze_resume("resume.pdf", jd)
analysis_id = reveilio.export_result(result, job_title="Backend Engineer")
print(f"Stored as: {analysis_id}")
Batch export
# Analyze a folder and export all results
results = reveilio.analyze_folder("./resumes", jd)
ids = reveilio.export_results(results, job_title="Backend Engineer")
print(f"Stored {len(ids)} analyses")
Each result is assigned a unique analysis_id (UUID). You can also
pass your own ID:
reveilio.export_result(result, analysis_id="my-custom-id-001")
Importing results from the database
Load by ID
result = reveilio.import_result("analysis-uuid-here")
print(result.overall_score, result.recommendation)
Load recent results
# Load the 10 most recent analyses
results = reveilio.import_results(limit=10)
# Load with pagination
page_2 = reveilio.import_results(limit=10, offset=10)
# Sort by score instead of date
top_scores = reveilio.import_results(order_by="overall_score", descending=True)
List analyses (metadata only)
When you just need a summary without the full analysis data:
entries = reveilio.list_analyses(limit=20)
for entry in entries:
print(f"{entry['candidate_name']}: {entry['overall_score']} - {entry['recommendation']}")
Returns dicts with: analysis_id, candidate_name,
overall_score, confidence_level, recommendation,
job_title, created_at.
Querying with filters
Use query_results() to find analyses matching specific criteria.
All filters are optional and combined with AND logic:
# Candidates scoring above 80
top = reveilio.query_results(min_score=80)
# Shortlisted candidates for a specific role
shortlisted = reveilio.query_results(
recommendation="Shortlist",
job_title="Backend Engineer",
)
# Search by candidate name
matches = reveilio.query_results(candidate_name="John")
# Combine multiple filters
precise = reveilio.query_results(
min_score=70,
max_score=95,
recommendation="Shortlist",
limit=50,
)
| Filter | Type | Description |
|---|---|---|
candidate_name | str | Partial name match (case-insensitive for MongoDB) |
min_score | float | Minimum overall score (inclusive) |
max_score | float | Maximum overall score (inclusive) |
recommendation | str | Exact match: "Shortlist", "Needs Review", or "Not Suitable" |
job_title | str | Partial match on the job title tag |
limit | int | Max results to return (default: 100) |
Deleting results
# Delete by analysis ID
deleted = reveilio.delete_result("analysis-uuid-here")
if deleted:
print("Record removed")
Disconnecting
Close the database connection when you are done:
reveilio.disconnect_db()
Calling connect_db() again after disconnecting opens a fresh connection.
If you call connect_db() while already connected, the old connection is
closed automatically before opening the new one.
Switching databases at runtime
Just call connect_db() again. The previous connection is closed automatically:
# Start with SQLite for local dev
reveilio.connect_db("sqlite", filepath="dev.db")
reveilio.export_results(results)
# Switch to PostgreSQL for production
reveilio.connect_db("postgresql", host="prod-db.internal", database="hiring", ...)
reveilio.export_results(results)
Database schema
Reveilio automatically creates the required table (or collection for MongoDB) on first connection. The schema stores both queryable metadata columns and the full analysis payload as JSON:
| Column | Type | Description |
|---|---|---|
id | INTEGER / SERIAL | Auto-increment primary key |
analysis_id | VARCHAR (unique) | UUID or custom identifier |
candidate_name | VARCHAR | Extracted from candidate_data |
overall_score | FLOAT | The numeric match score (0–100) |
confidence_level | VARCHAR | High / Medium / Low |
recommendation | VARCHAR | Shortlist / Needs Review / Not Suitable |
job_title | VARCHAR | User-supplied job title tag |
data | JSON / JSONB | Full AnalysisResult payload |
created_at | TIMESTAMP | When the record was stored |
updated_at | TIMESTAMP | Last update timestamp |
Indexes are created on analysis_id (unique), candidate_name,
overall_score, and recommendation for fast querying.
Custom table name
By default the table is called reveilio_analyses. You can change it:
reveilio.connect_db("sqlite", table_name="q1_hiring_2026")
Full workflow example
import reveilio
# 1. Configure LLM
reveilio.configure(provider="gemini", api_key="AIza...")
# 2. Connect to database
reveilio.connect_db("sqlite", filepath="hiring_q1.db")
# 3. Run analysis
jd = reveilio.JobDescription.from_file("backend_jd.pdf")
results = reveilio.analyze_folder("./resumes", jd)
# 4. Export to database
ids = reveilio.export_results(results, job_title="Backend Engineer")
print(f"Saved {len(ids)} candidates")
# 5. Query later
shortlisted = reveilio.query_results(
recommendation="Shortlist",
min_score=75,
)
for r in shortlisted:
name = r.candidate_data.name if r.candidate_data else "Unknown"
print(f" {name}: {r.overall_score}/100 — {r.recommendation}")
# 6. Generate PDF reports for shortlisted
for r in shortlisted:
name = r.candidate_data.name.replace(" ", "_") if r.candidate_data else "candidate"
reveilio.save_report_pdf(r, f"reports/{name}.pdf")
# 7. Disconnect when done
reveilio.disconnect_db()
Continue to Guides.