database.create_registration_db
@file create_registration_db.py @brief Initializes the SQLite registration database from registration_sections.json.
@details This module creates the registration.db SQLite database and populates it with course section data from registration_sections.json. It is intended to be run once to initialize the database. For subsequent refreshes (upsert on conflict), use refresh_registration.py instead.
The database schema includes a UNIQUE constraint on course_code, so duplicate entries are silently ignored (INSERT OR IGNORE). Four indexes are created for fast querying by department, course code, status, and instructor.
Database schema: @code CREATE TABLE courses ( id INTEGER PRIMARY KEY AUTOINCREMENT, course_code TEXT NOT NULL UNIQUE, department TEXT, course_number TEXT, section TEXT, name TEXT, status TEXT, seats_open INTEGER, seats_total INTEGER, credits TEXT, instructor TEXT, days_time TEXT, location TEXT, method TEXT, begin_date TEXT, end_date TEXT, scraped_at TEXT ); @endcode
@author Data Pipeline — CSC 212 AI Academic Advising Platform @date 2026
@par Input registration_sections.json — scraped course section data
@par Output registration.db — initialized SQLite database
@par Dependencies - sqlite3 (stdlib) - json (stdlib) - os (stdlib)
@par Usage python create_registration_db.py
@note Run scrape_registration_sections.py or refresh_registration.py first to generate registration_sections.json before running this script.
1# ============================================================================= 2# 3# Copyright 2026 4# 5# Author: Noel Mensah 6# GitHub: https://github.com/LSilver17/CSC212---AI-Agent 7# 8# ============================================================================= 9 10""" 11@file create_registration_db.py 12@brief Initializes the SQLite registration database from registration_sections.json. 13 14@details 15This module creates the registration.db SQLite database and populates it with 16course section data from registration_sections.json. It is intended to be run 17once to initialize the database. For subsequent refreshes (upsert on conflict), 18use refresh_registration.py instead. 19 20The database schema includes a UNIQUE constraint on course_code, so duplicate 21entries are silently ignored (INSERT OR IGNORE). Four indexes are created for 22fast querying by department, course code, status, and instructor. 23 24Database schema: 25@code 26CREATE TABLE courses ( 27 id INTEGER PRIMARY KEY AUTOINCREMENT, 28 course_code TEXT NOT NULL UNIQUE, 29 department TEXT, 30 course_number TEXT, 31 section TEXT, 32 name TEXT, 33 status TEXT, 34 seats_open INTEGER, 35 seats_total INTEGER, 36 credits TEXT, 37 instructor TEXT, 38 days_time TEXT, 39 location TEXT, 40 method TEXT, 41 begin_date TEXT, 42 end_date TEXT, 43 scraped_at TEXT 44); 45@endcode 46 47@author Data Pipeline — CSC 212 AI Academic Advising Platform 48@date 2026 49 50@par Input 51 registration_sections.json — scraped course section data 52 53@par Output 54 registration.db — initialized SQLite database 55 56@par Dependencies 57 - sqlite3 (stdlib) 58 - json (stdlib) 59 - os (stdlib) 60 61@par Usage 62 python create_registration_db.py 63 64@note Run scrape_registration_sections.py or refresh_registration.py first 65 to generate registration_sections.json before running this script. 66""" 67 68import json 69import sqlite3 70import os 71 72## @brief Path to the input registration sections JSON file. 73JSON_FILE = "registration_sections.json" 74 75## @brief Path to the output SQLite database file. 76DB_FILE = "registration.db" 77 78 79def create_db(json_file: str, db_file: str): 80 """ 81 @brief Creates the SQLite database and populates it from the JSON file. 82 83 @details 84 Reads all course sections from the JSON file, connects to (or creates) 85 the SQLite database at db_file, creates the courses table and indexes 86 if they do not exist, and inserts all course records using INSERT OR IGNORE 87 to skip duplicates based on the unique course_code constraint. 88 89 Indexes created: 90 - idx_department on courses(department) 91 - idx_course_code on courses(course_code) 92 - idx_status on courses(status) 93 - idx_instructor on courses(instructor) 94 95 @param json_file Path to the registration_sections.json input file. 96 @param db_file Path to the SQLite database file to create or update. 97 98 @par Side Effects 99 Creates or modifies the SQLite database file at db_file. 100 Prints a summary of inserted and skipped records on completion. 101 102 @throws FileNotFoundError if json_file does not exist (handled by caller). 103 @throws sqlite3.Error for individual record insert failures (logged, not raised). 104 """ 105 # Load JSON 106 with open(json_file, "r", encoding="utf-8") as f: 107 courses = json.load(f) 108 109 print(f"Loaded {len(courses)} course sections from {json_file}") 110 111 # Connect to SQLite (creates file if it doesn't exist) 112 conn = sqlite3.connect(db_file) 113 cursor = conn.cursor() 114 115 # Create table and indexes 116 cursor.executescript(""" 117 CREATE TABLE IF NOT EXISTS courses ( 118 id INTEGER PRIMARY KEY AUTOINCREMENT, 119 course_code TEXT NOT NULL, 120 department TEXT, 121 course_number TEXT, 122 section TEXT, 123 name TEXT, 124 status TEXT, 125 seats_open INTEGER, 126 seats_total INTEGER, 127 credits TEXT, 128 instructor TEXT, 129 days_time TEXT, 130 location TEXT, 131 method TEXT, 132 begin_date TEXT, 133 end_date TEXT, 134 scraped_at TEXT, 135 UNIQUE(course_code) 136 ); 137 138 CREATE INDEX IF NOT EXISTS idx_department ON courses(department); 139 CREATE INDEX IF NOT EXISTS idx_course_code ON courses(course_code); 140 CREATE INDEX IF NOT EXISTS idx_status ON courses(status); 141 CREATE INDEX IF NOT EXISTS idx_instructor ON courses(instructor); 142 """) 143 144 # Insert courses 145 inserted = 0 146 skipped = 0 147 148 for course in courses: 149 try: 150 cursor.execute(""" 151 INSERT OR IGNORE INTO courses ( 152 course_code, department, course_number, section, 153 name, status, seats_open, seats_total, credits, 154 instructor, days_time, location, method, 155 begin_date, end_date, scraped_at 156 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 157 """, ( 158 course.get("course_code"), 159 course.get("department"), 160 course.get("course_number"), 161 course.get("section"), 162 course.get("name"), 163 course.get("status"), 164 course.get("seats_open"), 165 course.get("seats_total"), 166 course.get("credits"), 167 course.get("instructor"), 168 course.get("days_time"), 169 course.get("location"), 170 course.get("method"), 171 course.get("begin_date"), 172 course.get("end_date"), 173 course.get("scraped_at"), 174 )) 175 if cursor.rowcount > 0: 176 inserted += 1 177 else: 178 skipped += 1 179 except sqlite3.Error as e: 180 print(f" Error inserting {course.get('course_code')}: {e}") 181 182 conn.commit() 183 conn.close() 184 185 print(f"✅ Database created: {db_file}") 186 print(f" Inserted: {inserted} courses") 187 print(f" Skipped: {skipped} duplicates") 188 189 190if __name__ == "__main__": 191 if not os.path.exists(JSON_FILE): 192 print(f"❌ {JSON_FILE} not found. Run scrape_registration_sections.py first.") 193 else: 194 create_db(JSON_FILE, DB_FILE)
80def create_db(json_file: str, db_file: str): 81 """ 82 @brief Creates the SQLite database and populates it from the JSON file. 83 84 @details 85 Reads all course sections from the JSON file, connects to (or creates) 86 the SQLite database at db_file, creates the courses table and indexes 87 if they do not exist, and inserts all course records using INSERT OR IGNORE 88 to skip duplicates based on the unique course_code constraint. 89 90 Indexes created: 91 - idx_department on courses(department) 92 - idx_course_code on courses(course_code) 93 - idx_status on courses(status) 94 - idx_instructor on courses(instructor) 95 96 @param json_file Path to the registration_sections.json input file. 97 @param db_file Path to the SQLite database file to create or update. 98 99 @par Side Effects 100 Creates or modifies the SQLite database file at db_file. 101 Prints a summary of inserted and skipped records on completion. 102 103 @throws FileNotFoundError if json_file does not exist (handled by caller). 104 @throws sqlite3.Error for individual record insert failures (logged, not raised). 105 """ 106 # Load JSON 107 with open(json_file, "r", encoding="utf-8") as f: 108 courses = json.load(f) 109 110 print(f"Loaded {len(courses)} course sections from {json_file}") 111 112 # Connect to SQLite (creates file if it doesn't exist) 113 conn = sqlite3.connect(db_file) 114 cursor = conn.cursor() 115 116 # Create table and indexes 117 cursor.executescript(""" 118 CREATE TABLE IF NOT EXISTS courses ( 119 id INTEGER PRIMARY KEY AUTOINCREMENT, 120 course_code TEXT NOT NULL, 121 department TEXT, 122 course_number TEXT, 123 section TEXT, 124 name TEXT, 125 status TEXT, 126 seats_open INTEGER, 127 seats_total INTEGER, 128 credits TEXT, 129 instructor TEXT, 130 days_time TEXT, 131 location TEXT, 132 method TEXT, 133 begin_date TEXT, 134 end_date TEXT, 135 scraped_at TEXT, 136 UNIQUE(course_code) 137 ); 138 139 CREATE INDEX IF NOT EXISTS idx_department ON courses(department); 140 CREATE INDEX IF NOT EXISTS idx_course_code ON courses(course_code); 141 CREATE INDEX IF NOT EXISTS idx_status ON courses(status); 142 CREATE INDEX IF NOT EXISTS idx_instructor ON courses(instructor); 143 """) 144 145 # Insert courses 146 inserted = 0 147 skipped = 0 148 149 for course in courses: 150 try: 151 cursor.execute(""" 152 INSERT OR IGNORE INTO courses ( 153 course_code, department, course_number, section, 154 name, status, seats_open, seats_total, credits, 155 instructor, days_time, location, method, 156 begin_date, end_date, scraped_at 157 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 158 """, ( 159 course.get("course_code"), 160 course.get("department"), 161 course.get("course_number"), 162 course.get("section"), 163 course.get("name"), 164 course.get("status"), 165 course.get("seats_open"), 166 course.get("seats_total"), 167 course.get("credits"), 168 course.get("instructor"), 169 course.get("days_time"), 170 course.get("location"), 171 course.get("method"), 172 course.get("begin_date"), 173 course.get("end_date"), 174 course.get("scraped_at"), 175 )) 176 if cursor.rowcount > 0: 177 inserted += 1 178 else: 179 skipped += 1 180 except sqlite3.Error as e: 181 print(f" Error inserting {course.get('course_code')}: {e}") 182 183 conn.commit() 184 conn.close() 185 186 print(f"✅ Database created: {db_file}") 187 print(f" Inserted: {inserted} courses") 188 print(f" Skipped: {skipped} duplicates")
@brief Creates the SQLite database and populates it from the JSON file.
@details Reads all course sections from the JSON file, connects to (or creates) the SQLite database at db_file, creates the courses table and indexes if they do not exist, and inserts all course records using INSERT OR IGNORE to skip duplicates based on the unique course_code constraint.
Indexes created:
- idx_department on courses(department)
- idx_course_code on courses(course_code)
- idx_status on courses(status)
- idx_instructor on courses(instructor)
@param json_file Path to the registration_sections.json input file. @param db_file Path to the SQLite database file to create or update.
@par Side Effects Creates or modifies the SQLite database file at db_file. Prints a summary of inserted and skipped records on completion.
@throws FileNotFoundError if json_file does not exist (handled by caller). @throws sqlite3.Error for individual record insert failures (logged, not raised).