diff --git a/athena/athena/models/db_exercise.py b/athena/athena/models/db_exercise.py index 13fd5593e..323cc5527 100644 --- a/athena/athena/models/db_exercise.py +++ b/athena/athena/models/db_exercise.py @@ -1,18 +1,27 @@ from sqlalchemy import Column, String, Float, JSON, Enum as SqlEnum - +from sqlalchemy.orm import relationship +from athena.database import Base from athena.schemas import ExerciseType from .model import Model from .big_integer_with_autoincrement import BigIntegerWithAutoincrement -class DBExercise(Model): +class DBExercise(Model, Base): + __tablename__ = "exercise" id = Column(BigIntegerWithAutoincrement, primary_key=True, index=True, nullable=False) lms_url = Column(String, index=True, nullable=False) title = Column(String, index=True, nullable=False) - type = Column(SqlEnum(ExerciseType), index=True, nullable=False) max_points = Column(Float, index=True, nullable=False) bonus_points = Column(Float, index=True, nullable=False) grading_instructions = Column(String) problem_statement = Column(String) grading_criteria = Column(JSON, nullable=True) meta = Column(JSON, nullable=False) + + # Polymorphism, discriminator attribute + type = Column(SqlEnum(ExerciseType), index=True, nullable=False) + + __mapper_args__ = { + 'polymorphic_identity': 'exercise', + 'polymorphic_on': 'type' + } \ No newline at end of file diff --git a/athena/athena/models/db_modeling_exercise.py b/athena/athena/models/db_modeling_exercise.py index 450b32e77..818724ab8 100644 --- a/athena/athena/models/db_modeling_exercise.py +++ b/athena/athena/models/db_modeling_exercise.py @@ -1,14 +1,17 @@ -from sqlalchemy import Column, String +from athena.schemas.exercise_type import ExerciseType +from sqlalchemy import Column, String, ForeignKey from sqlalchemy.orm import relationship - -from athena.database import Base from .db_exercise import DBExercise - - -class DBModelingExercise(DBExercise, Base): +from .big_integer_with_autoincrement import BigIntegerWithAutoincrement +class DBModelingExercise(DBExercise): __tablename__ = "modeling_exercises" - example_solution: str = Column(String) # type: ignore - + example_solution = Column(String) # type: ignore + + id = Column(BigIntegerWithAutoincrement, ForeignKey('exercise.id'), primary_key=True) submissions = relationship("DBModelingSubmission", back_populates="exercise") feedbacks = relationship("DBModelingFeedback", back_populates="exercise") + + __mapper_args__ = { + 'polymorphic_identity': ExerciseType.modeling.value + } \ No newline at end of file diff --git a/athena/athena/models/db_programming_exercise.py b/athena/athena/models/db_programming_exercise.py index b558dd58f..3060e5831 100644 --- a/athena/athena/models/db_programming_exercise.py +++ b/athena/athena/models/db_programming_exercise.py @@ -1,13 +1,15 @@ -from sqlalchemy import Column, String +from athena.schemas.exercise_type import ExerciseType +from sqlalchemy import Column, String, ForeignKey from sqlalchemy.orm import relationship -from athena.database import Base from .db_exercise import DBExercise +from .big_integer_with_autoincrement import BigIntegerWithAutoincrement -class DBProgrammingExercise(DBExercise, Base): +class DBProgrammingExercise(DBExercise): __tablename__ = "programming_exercises" + id = Column(BigIntegerWithAutoincrement, ForeignKey('exercise.id'), primary_key=True) programming_language: str = Column(String, nullable=False) # type: ignore solution_repository_uri: str = Column(String, nullable=False) # type: ignore template_repository_uri: str = Column(String, nullable=False) # type: ignore @@ -15,3 +17,7 @@ class DBProgrammingExercise(DBExercise, Base): submissions = relationship("DBProgrammingSubmission", back_populates="exercise") feedbacks = relationship("DBProgrammingFeedback", back_populates="exercise") + + __mapper_args__ = { + 'polymorphic_identity': ExerciseType.programming.value + } \ No newline at end of file diff --git a/athena/athena/models/db_text_exercise.py b/athena/athena/models/db_text_exercise.py index f3c2823ef..05df9e5c0 100644 --- a/athena/athena/models/db_text_exercise.py +++ b/athena/athena/models/db_text_exercise.py @@ -1,14 +1,20 @@ -from sqlalchemy import Column, String +from athena.schemas.exercise_type import ExerciseType +from sqlalchemy import Column, String, ForeignKey from sqlalchemy.orm import relationship -from athena.database import Base from .db_exercise import DBExercise +from .big_integer_with_autoincrement import BigIntegerWithAutoincrement -class DBTextExercise(DBExercise, Base): +class DBTextExercise(DBExercise): __tablename__ = "text_exercises" + id = Column(BigIntegerWithAutoincrement, ForeignKey('exercise.id'), primary_key=True) example_solution: str = Column(String) # type: ignore submissions = relationship("DBTextSubmission", back_populates="exercise") feedbacks = relationship("DBTextFeedback", back_populates="exercise") + + __mapper_args__ = { + 'polymorphic_identity': ExerciseType.text.value + } \ No newline at end of file diff --git a/athena/athena/schemas/grading_criterion.py b/athena/athena/schemas/grading_criterion.py index 15225a7dc..f13e23768 100644 --- a/athena/athena/schemas/grading_criterion.py +++ b/athena/athena/schemas/grading_criterion.py @@ -26,4 +26,4 @@ class GradingCriterion(Schema, ABC): {"credits": 0.0, "gradingScale": "Bad", "instructionDescription": "Some instructions", "feedback": "Try again!", "usageCount": 0}]) class StructuredGradingCriterion(BaseModel): - criteria: List[GradingCriterion] \ No newline at end of file + criteria: List[GradingCriterion]