Final Project β Scripture & SQL
CS354 Β· Database Management Systems Β· Calvin University
A Biblical Data InvestigationΒΆ
For thousands of years, scholars read the Bible one verse at a time β searching by hand, marking pages, keeping indexes. You are about to read all 31,102 verses at once.
The dataset you will work with is not just a collection of texts. It is a knowledge graph of ancient civilization, converted into a relational database and loaded into Supabase. Behind each table row is a thread connecting three millennia of recorded history: genealogies that span forty generations, places mapped to coordinates, and people referenced across books written centuries apart.
SQL gives you something no scribe, theologian, or historian ever had: the power to ask questions at scale. Who appears in both the Old and New Testaments? Which geographic region is mentioned most across all 66 books? How many generations of descendants does Abraham have in the recorded text? These are not theological questions β they are queries. And by the end of this project, you will have the tools to answer them.
The DatasetΒΆ
The database contains nine tables drawn from a Neo4j graph database of the King James Bible, enriched with biblical reference data.
| Table | Rows | What it holds |
|---|---|---|
testaments | 2 | Old Testament and New Testament |
books | 66 | All canonical books, in order |
chapters | 1,189 | Every chapter, linked to its book |
verses | 31,102 | Every verse in the KJV, with full text |
persons | 3,069 | Named biblical persons |
places | 1,274 | Geographic places, including coordinates |
verse_persons | ~28,000 | Which persons appear in which verses |
verse_places | ~6,000 | Which places appear in which verses |
genealogy | 1,785 | Recorded parentβchild relationships |
The verse_code FormatΒΆ
Each verse has a unique verse_code in the format BBCCCVVV (8 digits):
BB β book number (01β66, in canonical order)
CCC β chapter number (001β150)
VVV β verse number within the chapter (001β176)
For example, Genesis 1:1 is 01001001 and John 3:16 is 43003016.
The Junction Table Join PatternΒΆ
The tables verse_persons, verse_places, and genealogy link rows through the id column of each entity table. Always join them like this:
JOIN verse_persons vp ON vp.verse_id = v.id
JOIN persons p ON vp.person_id = p.idSchema ReferenceΒΆ
Quick column reference
testaments (id, name)
books (id, title, short_name, book_order, slug, osis_ref, testament_id)
chapters (id, chapter_num, osis_ref, book_id)
verses (id, verse_code, verse_num, verse_text, osis_ref, chapter_id)
persons (id, person_ref, name, title, gender, slug, status)
places (id, place_ref, name, feature_type, latitude, longitude, status)
verse_persons (verse_id β verses.id, person_id β persons.id)
verse_places (verse_id β verses.id, place_id β places.id)
genealogy (person_id β persons.id, parent_id β persons.id)What You Will DoΒΆ
You and your partner will complete 15 guided SQL queries and one open investigation. All work lives in a single file β queries.py.
Your workflowΒΆ
Accept the GitHub Classroom assignment from the link on Moodle.
Clone the repository to your machine (or open it on
coder.cs.calvin.edu).Create a Python virtual environment and install dependencies.
Copy
.env.exampleto.env, then paste the database credentials from Moodle into it.Run
python app.pyand openhttp://localhost:5000.Read the docstring for each function in
queries.py, write your SQL, save the file, and refresh the dashboard.When all 15 structured queries are green, fill in the three
RESEARCH_*strings at the bottom ofqueries.py.Record a 2-minute video where both partners explain your research question, walk through your SQL, and share your findings. Upload it to YouTube (unlisted) or Vimeo and copy the link.
Commit and push your final
queries.py:git add queries.py,git commit -m "Complete final project",git push.Submit the video URL through the Moodle assignment link.
| File | Edit it? |
|---|---|
queries.py | β Yes β the only file you need to touch |
app.py | π« No |
grade.py | π« No |
.env | π« Do not commit this file |
SetupΒΆ
# Clone (replace URL with your GitHub Classroom link)
git clone <your-repo-url>
cd final-project
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # Mac / Linux
.venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
# Create your .env from the template, then paste the credentials from Moodle
cp .env.example .env
# Open .env and fill in the values posted on Moodle
# Start the dashboard
python app.py
# β open http://localhost:5000Checking Your ScoreΒΆ
You have two ways to see your current score:
Option A β Web app (recommended for detailed feedback)
python app.py
# Open http://localhost:5000Shows a live dashboard with per-query results, sample rows, and error messages.
Option B β Command line (quick check, no browser needed)
python autograder.pyPrints a compact summary:
============================================================
CS354 Β· Scripture & SQL Β· Autograder
============================================================
Part 1 Β· Basic DQL
----------------------------------------
β q1 Books in Canonical Order 3/3 pts
β q2 Verse Counts per Book 3/3 pts
β q3 Chapters with More than 40 Verses 0/3 pts
Β· q4 Find a Verse by Reference 0/3 pts
...
============================================================
Questions correct : 12 / 15
Auto-graded score : 56 / 70 pts
(Part 5 Β· Open Investigation is graded separately)
============================================================Symbols: β correct Β· β wrong answer Β· Β· not attempted Β· ! query error
Exploring the Database with SQLTools (VS Code)ΒΆ
Before writing your queries in queries.py, it helps to browse the tables and run exploratory SQL directly inside VS Code. SQLTools is a free extension that gives you a database explorer panel and an in-editor SQL runner β no separate client needed.
Step 1 β Install the extensionsΒΆ
Open the Extensions panel in VS Code (Cmd+Shift+X on Mac, Ctrl+Shift+X on Windows) and install both:
SQLTools β search for
SQLToolsby Matheus Teixeira (mtxr.sqltools)SQLTools PostgreSQL/CockroachDB Driver β search for
SQLTools PostgreSQL(mtxr.sqltools-driver-pg)
Step 2 β Create a new connectionΒΆ
Click the SQLTools icon in the left Activity Bar (looks like a cylinder).
Click Add New Connection.
Choose PostgreSQL as the driver.
Fill in the connection form using the credentials from your
.envfile:
| Field | Value |
|---|---|
| Connection name | Scripture & SQL (or anything you like) |
| Server / Host | value of SUPABASE_HOST in your .env |
| Port | 5432 |
| Database | postgres |
| Username | value of SUPABASE_USER in your .env |
| Password | value of SUPABASE_PASSWORD in your .env |
| SSL | Enabled |
| Default schema | bible |
Click Test Connection to verify it works, then Save.
Step 3 β Browse the tablesΒΆ
Once connected, expand the connection in the SQLTools sidebar. You will see a Tables folder listing all nine tables. Click any table name to see its columns and types. Right-click a table and choose Select Top 10 to preview its data instantly.
Step 4 β Run exploratory queriesΒΆ
Open any .sql file (or create a new one) and write a query. To run it:
Highlight the query text and press
Ctrl+ECtrl+E(run selection), orUse the Run on active connection button in the editor toolbar.
Results appear in a panel at the bottom of the screen, paginated and copyable.
A few good queries to start with:
-- What do the first few verses look like?
SELECT b.title, c.chapter_num, v.verse_num, v.verse_text
FROM verses v
JOIN chapters c ON v.chapter_id = c.id
JOIN books b ON c.book_id = b.id
ORDER BY b.book_order, c.chapter_num, v.verse_num
LIMIT 20;
-- Who are the persons in the database?
SELECT name, gender, title FROM persons ORDER BY name LIMIT 30;
-- What types of places exist?
SELECT feature_type, COUNT(*) AS total
FROM places
GROUP BY feature_type
ORDER BY total DESC;Use SQLTools to experiment freely β it is the ideal environment for drafting your Part 5 research query before copying the final version into queries.py.
Query TasksΒΆ
Part 1 β Basic DQL (15 pts)ΒΆ
Five queries covering SELECT, WHERE, ORDER BY, GROUP BY, and HAVING. Each is worth 3 points.
| # | Title | Key skill |
|---|---|---|
| Q1 | Books in Canonical Order | JOIN across two tables |
| Q2 | Verse Counts per Book | COUNT + GROUP BY |
| Q3 | Chapters with More than 40 Verses | GROUP BY + HAVING |
| Q4 | Find a Verse by Reference | WHERE on verse_code |
| Q5 | Gender Distribution of Persons | COALESCE + GROUP BY |
Part 2 β Joins & Subqueries (25 pts)ΒΆ
Five queries requiring joins across multiple tables or subqueries. Each is worth 5 points.
| # | Title | Key skill |
|---|---|---|
| Q6 | Most Mentioned Persons | Junction table join |
| Q7 | Most Mentioned Places | Junction table join |
| Q8 | Cross-Testament Persons | Conditional aggregation |
| Q9 | Books with No Place Mentions | Subquery or LEFT JOIN with NULL check |
| Q10 | Verses Mentioning a Person and a Place | Two subqueries combined |
Part 3 β Window Functions (15 pts)ΒΆ
Three queries requiring window functions. Each is worth 5 points.
| # | Title | Points |
|---|---|---|
| Q11 | Verse Count Rank by Book | 5 |
| Q12 | Running Total of Verses | 5 |
| Q13 | Person Mention Percentile | 5 |
Part 4 β Common Table Expressions (15 pts)ΒΆ
Two queries that must use a WITH clause.
| # | Title | Points |
|---|---|---|
| Q14 | Books Above Average Verse Count | 6 |
| Q15 | Descendants of a Biblical Figure (recursive CTE) | 9 |
Part 5 β Open Investigation (30 pts)ΒΆ
Design and answer your own question about the biblical data. This part has two deliverables: code in queries.py and a short video.
Part 5a β CodeΒΆ
Fill in three strings at the bottom of queries.py:
RESEARCH_QUESTIONβ one or two sentences describing what you are investigating and why it is interesting.RESEARCH_QUERYβ a valid SQL query using at least one technique from the course.RESEARCH_FINDINGSβ 3β5 sentences interpreting your results.
Part 5b β 2-Minute VideoΒΆ
Record a short video (maximum 2 minutes) in which both team members explain:
Your question β what you decided to investigate and why you chose it.
Your query β walk through your SQL briefly, explaining the key technique you used.
Your findings β what the data revealed, and what surprised you or made you think.
The video does not need to be polished β a screen recording with your voice is fine. Both partners must speak. Upload it to YouTube (unlisted) or Vimeo and submit the URL on Moodle.
Some directions to consider:
Which book has the highest ratio of place mentions to verse count?
Are female persons mentioned more in the Old or New Testament?
Which chapter contains the most unique persons mentioned in a single chapter?
What is the average verse length (in characters) per book?
How far does the genealogical record extend from a single ancestor?
GradingΒΆ
| Section | Points | How graded |
|---|---|---|
| Part 1 β Basic DQL | 15 | Automatic (hash comparison) |
| Part 2 β Joins & Subqueries | 25 | Automatic (hash comparison) |
| Part 3 β Window Functions | 15 | Automatic (hash comparison) |
| Part 4 β CTEs | 15 | Automatic (hash comparison) |
| Part 5 β Open Investigation | 30 | Instructor review (code + video) |
| Total | 100 |
Each auto-graded query is all-or-nothing: full points if the result set matches exactly (correct data and correct ordering), zero otherwise.
SubmissionΒΆ
This project has two separate submissions, both due by the deadline posted on Moodle.
1. Code β GitHub Classroom
Push your completed queries.py to the GitHub Classroom repository:
git add queries.py
git commit -m "Complete final project"
git push2. Video β Moodle
Submit the URL of your 2-minute investigation video through the Moodle assignment link. Make sure the link is publicly accessible (or shared with your instructor) before submitting.
Academic IntegrityΒΆ
All queries you submit must be your own teamβs work. Do not copy queries from other teams or use AI tools to write them for you. External references β documentation, textbooks, class notes β are appropriate and expected.