Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 173 additions & 60 deletions seed_db.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,34 @@
import os
import sys
import random
import time

# Add the Backend directory to the sys.path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from datetime import date
from datetime import date, datetime, timedelta, timezone
from sqlalchemy.orm import Session
from app.db.session import SessionLocal, engine
from app.db.base import Base
from app import crud, schemas
from app.models.department import Department
from app.models.course import Course
from app.models.academic_session import AcademicSession
from app.models.course_assignment import CourseAssignment
from app.models.attendance_session import AttendanceSession
from app.models.attendance_record import AttendanceRecord

# Dummy Data Pools
FIRST_NAMES = ["John", "Jane", "Michael", "Sarah", "David", "Emma", "Daniel", "Olivia", "James", "Sophia", "Matthew", "Ava", "Joseph", "Isabella", "Samuel", "Mia"]
LAST_NAMES = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Hernandez", "Lopez", "Gonzalez"]
LEVELS = ["100", "200", "300", "400", "500"]

def get_random_name():
return f"{random.choice(FIRST_NAMES)} {random.choice(LAST_NAMES)}"

def seed():
start_time_benchmark = time.time()

print("Dropping all tables...")
Base.metadata.drop_all(bind=engine)
print("Recreating all tables...")
Expand All @@ -23,48 +37,64 @@ def seed():
db: Session = SessionLocal()

try:
# Create Admin
# 1. Create Admin
print("Seeding admin...")
admin_in = schemas.UserCreate(
email="admin@attendease.com",
password="admin123",
full_name="Super Admin",
role="ADMIN",
)
admin = crud.user.create(db, obj_in=admin_in)

# Create Department
print("Seeding department...")
dept = Department(name="Computer Science")
db.add(dept)
crud.user.create(db, obj_in=admin_in)

# 2. Create Departments
print("Seeding departments...")
dept_names = ["Computer Science", "Mathematics", "Electrical Engineering"]
departments = []
for name in dept_names:
dept = Department(name=name)
db.add(dept)
departments.append(dept)
db.commit()
db.refresh(dept)

# Create Lecturer
print("Seeding lecturer...")
lecturer_in = schemas.LecturerCreate(
email="lecturer@attendease.com",
password="lecturer123",
full_name="Dr. John Doe",
staff_id="STAFF123",
department_id=dept.id,
)
lecturer = crud.lecturer.create_with_user(db, obj_in=lecturer_in)

# Create Student
print("Seeding student...")
student_in = schemas.StudentCreate(
email="student@attendease.com",
password="student123",
full_name="Jane Smith",
student_id="STU123",
matric_number="CSC/2021/001",
department_id=dept.id,
level="300",
)
student = crud.student.create_with_user(db, obj_in=student_in)

# Create Academic Session
for d in departments:
db.refresh(d)

# 3. Create Lecturers
print("Seeding lecturers...")
lecturers = []
for i in range(1, 6):
dept = random.choice(departments)
lecturer_in = schemas.LecturerCreate(
email=f"lecturer{i}@attendease.com",
password="lecturer123",
full_name=f"Dr. {get_random_name()}",
staff_id=f"STAFF{1000 + i}",
department_id=dept.id,
)
lecturer = crud.lecturer.create_with_user(db, obj_in=lecturer_in)
lecturers.append(lecturer)

# 4. Create Students
print("Seeding students...")
students = []
for i in range(1, 21):
dept = random.choice(departments)
level = random.choice(LEVELS)
dept_code = dept.name[:3].upper()

student_in = schemas.StudentCreate(
email=f"student{i}@attendease.com",
password="student123",
full_name=get_random_name(),
student_id=f"STU{2000 + i}",
matric_number=f"{dept_code}/2021/{i:03d}",
department_id=dept.id,
level=level,
)
student = crud.student.create_with_user(db, obj_in=student_in)
students.append(student)

# 5. Create Academic Session
print("Seeding academic session...")
session = AcademicSession(
session_name="2025/2026",
Expand All @@ -77,32 +107,115 @@ def seed():
db.commit()
db.refresh(session)

# Create Course
print("Seeding course...")
course = Course(
course_code="CSC 301",
title="Introduction to Database Systems",
credit_units=3,
department_id=dept.id,
)
db.add(course)
# 6. Create Courses
print("Seeding courses...")
course_data = [
("CSC 301", "Database Systems", 3, departments[0].id),
("CSC 302", "Software Engineering", 3, departments[0].id),
("CSC 401", "Artificial Intelligence", 4, departments[0].id),
("MAT 101", "Calculus I", 3, departments[1].id),
("MAT 202", "Linear Algebra", 2, departments[1].id),
("MAT 305", "Differential Equations", 3, departments[1].id),
("EEE 201", "Circuit Theory", 3, departments[2].id),
("EEE 302", "Electromagnetics", 4, departments[2].id),
("EEE 405", "Digital Signal Processing", 3, departments[2].id),
]

courses = []
for code, title, units, dept_id in course_data:
course = Course(course_code=code, title=title, credit_units=units, department_id=dept_id)
db.add(course)
courses.append(course)
db.commit()
for c in courses:
db.refresh(c)

# 7. Create Course Assignments
print("Seeding course assignments...")
assignments = []
for course in courses:
eligible_lecturers = [l for l in lecturers if l.department_id == course.department_id]
lecturer = random.choice(eligible_lecturers) if eligible_lecturers else random.choice(lecturers)

assignment = CourseAssignment(
course_id=course.id,
lecturer_id=lecturer.user_id,
academic_session_id=session.id,
)
db.add(assignment)
assignments.append(assignment)
db.commit()
for a in assignments:
db.refresh(a)

# 8. Create Attendance Sessions and Records for visual graphs
print("Seeding robust historical attendance data (Bulk inserting for speed)...")
now = datetime.now(timezone.utc)

session_counter = 1
all_attendance_records = []

for assignment in assignments:
num_sessions = random.randint(5, 10)

course_dept_id = next(c.department_id for c in courses if c.id == assignment.course_id)
enrolled_students = [s for s in students if s.department_id == course_dept_id]

for _ in range(num_sessions):
days_ago = random.randint(0, 30)
hour_of_day = random.randint(8, 16)

start_time = (now - timedelta(days=days_ago)).replace(hour=hour_of_day, minute=0, second=0, microsecond=0)
end_time = start_time + timedelta(hours=random.choice([1, 2]))

# Create Session
att_session = AttendanceSession(
course_assignment_id=assignment.id,
session_date=start_time.date(),
start_time=start_time,
expires_at=end_time,
session_code=f"CODE{session_counter:04d}",
status="COMPLETED" if start_time < now else "ACTIVE",
geofencing_enabled=random.choice([True, False])
)
db.add(att_session)
db.flush()
session_counter += 1

# Create Records for enrolled students
for student in enrolled_students:
status = random.choices(
population=["PRESENT", "ABSENT"],
weights=[0.85, 0.15],
k=1
)[0]

if status == "PRESENT":
check_in_time = start_time + timedelta(minutes=random.randint(0, 15))
else:
check_in_time = end_time

record = AttendanceRecord(
session_id=att_session.id,
student_id=student.user_id,
check_in_time=check_in_time,
status=status
)
all_attendance_records.append(record)

# Bulk insert all records
print(f"Pushing {len(all_attendance_records)} attendance records to the database...")
db.add_all(all_attendance_records)
db.commit()
db.refresh(course)

# Create Course Assignment
print("Seeding course assignment...")
assignment_in = schemas.CourseAssignmentCreate(
course_id=course.id,
lecturer_id=lecturer.user_id,
academic_session_id=session.id,
)
crud.course_assignment.create(db, obj_in=assignment_in)

print("Seeding complete!")
print("\nCredentials:")
print("Admin: admin@attendease.com / admin123")
print("Lecturer: lecturer@attendease.com / lecturer123")
print("Student: student@attendease.com / student123")
elapsed_time = round(time.time() - start_time_benchmark, 2)
print(f"Seeding complete in {elapsed_time} seconds!")

print("\n--- Test Credentials ---")
print("Admin : admin@attendease.com / admin123")
print("Lecturer: lecturer1@attendease.com / lecturer123 (up to lecturer5@...)")
print("Student : student1@attendease.com / student123 (up to student20@...)")
print("------------------------\n")

except Exception as e:
print(f"Error during seeding: {e}")
Expand All @@ -112,4 +225,4 @@ def seed():


if __name__ == "__main__":
seed()
seed()
Loading