-
Notifications
You must be signed in to change notification settings - Fork 0
DatabaseSchema
The database for TA-Bot is a self-contained Docker container. The benefits of this are:
- Isolation: Docker ensures that the MySQL instance doesn't interfere with any other services on your system.
- Portability: You can easily move the Docker container to another machine without worrying about dependencies.
- Ease of Setup: Docker can automatically handle the setup and configuration of the MySQL instance.
-
Deployment: The Docker container is deployed using the
docker-compose.ymlfile in the root directory of the repository.
db:
image: mysql
restart: always
environment:
MYSQL_DATABASE: `example_database_name`
MYSQL_USER: 'example_user'
MYSQL_PASSWORD: 'example_password'
MYSQL_ROOT_PASSWORD: 'example_password'
ports:
- '127.0.0.1:3306:3306'
expose:
- '3306'
volumes:
- ./database:/var/lib/mysql
- ./init-db:/docker-entrypoint-initdb.d
-
Changes: If you want to change the database name, user, or password, you can do so by changing the environment variables in the
docker-compose.ymlfile. If you want to change the port that the database is exposed on, you can do so by changing the port in theportssection of thedocker-compose.ymlfile.
The docker image is built via an init.sql file that is located in the init-db directory. This file is run when the container is first created. If you want to make changes to the database schema, you can do so by modifying this file. If you want to make changes to the database schema after the container has been created, you can do so by connecting to the database image and running SQL commands manually, or by using MySQL Workbench.
- Editing the init.sql file will not change the database schema of an existing container. Changes made to this will only have an effect if you create a new database container.
The simplest way to view the database directly is by using MYSQL Workbench
- This can be downloaded here
Once created, you can add a new connection, using the following settings:
- Change the connection name to whatever you want
- Change the connection method to
Standard TCP/IP over SSH - The machine name is whatever server the docker container is running on
- Specifying the port as 3306, and setting the username and password credentials accordingly
Once you have connected to the database, you can view the database schema by clicking on the Schemas tab on the left side of the screen. You can then view the tables by clicking on the Tables tab on the left side of the screen.
Describing a database schema is a non-trivial task, while we hope this section provides some insight into the database schema, it is not a complete description.

Perhaps the easiest way to walk through the foreign key relations is to start with the models.py file. This maintains an internal structure of the database, which is used in multiple API repo's that leverage SQLAlchemy to interact with the database. If a change is made to the schema, it must be reflected in this file. For more detail and example of leveraging SQLAlchemy refer to the development guide
class Projects(db.Model):
__tablename__ = "Projects"
Id = Column(Integer, primary_key=True, autoincrement=True)
ClassId = Column(Integer, ForeignKey('Classes.Id'))
Name = Column(String)
Start = Column(Date)
End = Column(Date)
Language = Column(String)
Submissions=relationship('Submissions')
Levels=relationship('Levels')
StudentProgress=relationship('StudentProgress')
StudentUnlocks=relationship('StudentUnlocks')
solutionpath=Column(String)
AsnDescriptionPath = Column(String)
class Users(db.Model):
__tablename__ = "Users"
Id = Column(Integer, primary_key=True, autoincrement=True)
Username = Column(String)
Firstname = Column(String)
Lastname = Column(String)
Email = Column(String)
StudentNumber = Column(String)
Role = Column(Integer)
IsLocked = Column(Boolean)
ResearchGroup = Column(Integer)
Submissions=relationship('Submissions')
ClassAssignments=relationship('ClassAssignments')
LoginAttempts=relationship('LoginAttempts')
StudentProgress=relationship('StudentProgress')
StudentUnlocks=relationship('StudentUnlocks')
class Submissions(db.Model):
__tablename__ = "Submissions"
Id = Column(Integer, primary_key=True)
OutputFilepath = Column(String)
PylintFilepath = Column(String)
CodeFilepath = Column(String)
IsPassing = Column(Boolean)
NumberOfPylintErrors = Column(String)
Time = Column(Date)
User = Column(Integer, ForeignKey('Users.Id'))
Project = Column(Integer, ForeignKey('Projects.Id'))
SubmissionLevel =Column(String)
Points = Column(Integer)
StudentProgress=relationship('StudentProgress')
visible = Column(Integer)
class LoginAttempts(db.Model):
__tablename__ = "LoginAttempts"
Id = Column(Integer, primary_key=True)
Time = Column(Date)
IPAddress = Column(String)
Username = Column(String, ForeignKey('Users.Username'))
class Classes(db.Model):
__tablename__ = "Classes"
Id = Column(Integer, primary_key=True)
Name = Column(String)
Tid = Column(String)
class Labs(db.Model):
__tablename__ = "Labs"
Id = Column(Integer, primary_key=True)
Name = Column(String)
ClassId = Column(Integer, ForeignKey('Classes.Id'))
ClassAssignments=relationship('ClassAssignments')
class LectureSections(db.Model):
__tablename__ = "LectureSections"
Id = Column(Integer, primary_key=True)
Name = Column(String)
ClassId = Column(Integer, ForeignKey('Classes.Id'), primary_key=True)
ClassAssignments=relationship('ClassAssignments')
class ClassAssignments(db.Model):
__tablename__ = "ClassAssignments"
UserId = Column(Integer, ForeignKey('Users.Id'), primary_key=True)
ClassId = Column(Integer, ForeignKey('Classes.Id'), primary_key=True)
LabId = Column(Integer, ForeignKey('Labs.Id'))
LectureId = Column(Integer, ForeignKey('LectureSections.Id'))
class StudentProgress(db.Model):
__tablename__ = "StudentProgress"
UserId = Column(Integer, ForeignKey('Users.Id'), primary_key=True)
ProjectId = Column(Integer, ForeignKey('Projects.Id'), primary_key=True)
SubmissionId = Column(Integer, ForeignKey('Submissions.Id'), primary_key=True)
LatestLevel = Column(String)
class StudentUnlocks(db.Model):
__tablename__ = "StudentUnlocks"
UserId = Column(Integer, ForeignKey('Users.Id'), primary_key=True)
ProjectId = Column(Integer, ForeignKey('Projects.Id'), primary_key=True)
Time = Column(DateTime)
class Config(db.Model):
__tablename__ = "Config"
Name = Column(String, primary_key=True)
Value = Column(String)
class Levels(db.Model):
__tablename__ = "Levels"
Id = Column(Integer, primary_key=True)
ProjectId = Column(Integer, ForeignKey('Projects.Id'))
Name=Column(String)
Order=Column(Integer)
Points=Column(Integer)
class Testcases(db.Model):
__tablename__ = "Testcases"
Id = Column(Integer, primary_key=True, autoincrement=True)
ProjectId = Column(Integer, ForeignKey('Projects.Id'))
LevelId = Column(Integer, ForeignKey("Levels.Id"))
Name = Column(String)
Description = Column(String)
input = Column(String)
Output = Column(String)
IsHidden = Column(Boolean)
additionalfilepath = Column(String)
class GPTLogs(db.Model):
__tablename__ = "GPTLogs"
Qid = Column(Integer, primary_key=True, autoincrement=True)
SubmissionId = Column(Integer, ForeignKey('Submissions.Id'))
GPTResponse = Column(String)
StudentFeedback = Column(Integer)
Type = Column(Integer)
class ChatGPTkeys(db.Model):
__tablename__ = "ChatGPTkeys"
idChatGPTkeys = Column(Integer, primary_key=True, autoincrement=True)
ChatGPTkeyscol = Column(String)
LastUsed = Column(DateTime)
class StudentQuestions(db.Model):
__tablename__ = "StudentQuestions"
Sqid = Column(Integer, primary_key=True, autoincrement=True)
StudentQuestionscol = Column(String)
ruling = Column(Integer)
dismissed = Column(Integer)
StudentId = Column(Integer, ForeignKey('Users.Id'))
TimeSubmitted = Column(DateTime)
projectId = Column(Integer, ForeignKey('Projects.Id'))
TimeAccepted = Column(DateTime)
TimeCompleted = Column(DateTime)
class StudentGrades(db.Model):
__tablename__ = "StudentGrades"
Sid = Column(Integer, ForeignKey('Users.Id'), primary_key=True)
Pid = Column(Integer, ForeignKey('Projects.Id'), primary_key=True)
Grade = Column(Integer)