Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

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.

TableRowsWhat it holds
testaments2Old Testament and New Testament
books66All canonical books, in order
chapters1,189Every chapter, linked to its book
verses31,102Every verse in the KJV, with full text
persons3,069Named biblical persons
places1,274Geographic places, including coordinates
verse_persons~28,000Which persons appear in which verses
verse_places~6,000Which places appear in which verses
genealogy1,785Recorded parent–child relationships

The verse_code FormatΒΆ

Each verse has a unique verse_code in the format BBCCCVVV (8 digits):

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.id

Schema 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ΒΆ

  1. Accept the GitHub Classroom assignment from the link on Moodle.

  2. Clone the repository to your machine (or open it on coder.cs.calvin.edu).

  3. Create a Python virtual environment and install dependencies.

  4. Copy .env.example to .env, then paste the database credentials from Moodle into it.

  5. Run python app.py and open http://localhost:5000.

  6. Read the docstring for each function in queries.py, write your SQL, save the file, and refresh the dashboard.

  7. When all 15 structured queries are green, fill in the three RESEARCH_* strings at the bottom of queries.py.

  8. 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.

  9. Commit and push your final queries.py: git add queries.py, git commit -m "Complete final project", git push.

  10. Submit the video URL through the Moodle assignment link.

FileEdit 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:5000

Checking 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:5000

Shows a live dashboard with per-query results, sample rows, and error messages.

Option B β€” Command line (quick check, no browser needed)

python autograder.py

Prints 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:

  1. SQLTools β€” search for SQLTools by Matheus Teixeira (mtxr.sqltools)

  2. SQLTools PostgreSQL/CockroachDB Driver β€” search for SQLTools PostgreSQL (mtxr.sqltools-driver-pg)

Step 2 β€” Create a new connectionΒΆ

  1. Click the SQLTools icon in the left Activity Bar (looks like a cylinder).

  2. Click Add New Connection.

  3. Choose PostgreSQL as the driver.

  4. Fill in the connection form using the credentials from your .env file:

FieldValue
Connection nameScripture & SQL (or anything you like)
Server / Hostvalue of SUPABASE_HOST in your .env
Port5432
Databasepostgres
Usernamevalue of SUPABASE_USER in your .env
Passwordvalue of SUPABASE_PASSWORD in your .env
SSLEnabled
Default schemabible
  1. 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:

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.

#TitleKey skill
Q1Books in Canonical OrderJOIN across two tables
Q2Verse Counts per BookCOUNT + GROUP BY
Q3Chapters with More than 40 VersesGROUP BY + HAVING
Q4Find a Verse by ReferenceWHERE on verse_code
Q5Gender Distribution of PersonsCOALESCE + GROUP BY

Part 2 β€” Joins & Subqueries (25 pts)ΒΆ

Five queries requiring joins across multiple tables or subqueries. Each is worth 5 points.

#TitleKey skill
Q6Most Mentioned PersonsJunction table join
Q7Most Mentioned PlacesJunction table join
Q8Cross-Testament PersonsConditional aggregation
Q9Books with No Place MentionsSubquery or LEFT JOIN with NULL check
Q10Verses Mentioning a Person and a PlaceTwo subqueries combined

Part 3 β€” Window Functions (15 pts)ΒΆ

Three queries requiring window functions. Each is worth 5 points.

#TitlePoints
Q11Verse Count Rank by Book5
Q12Running Total of Verses5
Q13Person Mention Percentile5

Part 4 β€” Common Table Expressions (15 pts)ΒΆ

Two queries that must use a WITH clause.

#TitlePoints
Q14Books Above Average Verse Count6
Q15Descendants 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:

Part 5b β€” 2-Minute VideoΒΆ

Record a short video (maximum 2 minutes) in which both team members explain:

  1. Your question β€” what you decided to investigate and why you chose it.

  2. Your query β€” walk through your SQL briefly, explaining the key technique you used.

  3. 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:


GradingΒΆ

SectionPointsHow graded
Part 1 β€” Basic DQL15Automatic (hash comparison)
Part 2 β€” Joins & Subqueries25Automatic (hash comparison)
Part 3 β€” Window Functions15Automatic (hash comparison)
Part 4 β€” CTEs15Automatic (hash comparison)
Part 5 β€” Open Investigation30Instructor review (code + video)
Total100

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 push

2. 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.