WorkoutRating
наследуется от Rating
. Когда вы создаете рейтинг тренировки, строка вставляется в Rating
и WorkoutRating
с тем же id
. WorkoutRating
и Workout
взаимосвязаны один-к-одному, но когда рейтинг тренировки создается, он вставляет новую строку в таблицу WorkoutRating
и устанавливает workout_id
null для старого рейтинга. Вместо этого я бы хотел, чтобы он обновил старый рейтинг. Я знаю, что могу сделать это в коде, но мне интересно, почему не работает однозначное отношение.
Также есть класс WOTrainerRating
, который наследуется от Rating
и создается, когда WorkoutRating
равен создан. Он также вставляет новую строку с тем же workout_id
, но не удаляет workout_id
в старой записи. (Я думаю, это потому, что на Workout
нет связи.) Я не думаю, что это влияет на поведение WorkoutRating, но я включил его на всякий случай.
BasicMixin
и PolymorphicMixin
- объекты с некоторыми методами и свойствами, ни один из которых здесь не используется. put()
- это удобный метод, который добавляет и фиксирует один элемент в сеансе базы данных. Я пропустил столбцы, не относящиеся к этому вопросу.
class Workout(BasicMixin, Base):
user_id = Column(
Integer, ForeignKey('users.id', ondelete='CASCADE'), index=True)
user = relationship('User', foreign_keys=[user_id], backref='workouts')
rating = relationship('WorkoutRating', uselist=False, back_populates='workout')
....
class Rating(PolymorphicMixin, Base):
__mapper_args__ = {
'polymorphic_on': discriminator,
'polymorphic_identity': 'rating'
}
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), index=True)
user = relationship('User')
discriminator = Column('type', String(50))
rating = Column(SmallInteger)
....
class WOTrainerRating(Rating):
__tablename__ = 'workout_trainers_ratings'
__mapper_args__ = {'polymorphic_identity': 'trainer'}
id = Column(
Integer,
ForeignKey('ratings.id', ondelete='CASCADE'),
primary_key=True)
trainer_id = Column(
Integer, ForeignKey('users.id', ondelete='CASCADE'))
trainer = relationship('User', backref='ratings')
workout_id = Column(
Integer, ForeignKey('workouts.id', ondelete='CASCADE'))
workout = relationship('Workout', backref='trainer_ratings')
workout_rating_id = Column(
Integer, ForeignKey('workouts_ratings.id', ondelete='CASCADE'))
workout_rating = relationship(
'WorkoutRating',
backref=backref(
'trainer_rating', cascade="all, delete-orphan", uselist=False),
foreign_keys=[workout_rating_id])
class WorkoutRating(Rating):
__tablename__ = 'workouts_ratings'
__mapper_args__ = {'polymorphic_identity': 'workout'}
id = Column(
Integer,
ForeignKey('ratings.id', ondelete='CASCADE'),
primary_key=True)
workout_id = Column(
Integer, ForeignKey('workouts.id', ondelete='CASCADE'),
index=True)
workout = relationship('Workout', back_populates='rating')
...
@classmethod
def rate(
cls,
user,
workout,
rating,
trainer_rating=None,
...):
if trainer_rating:
trainer_rating = WOTrainerRating(
user=user,
rating=trainer_rating,
trainer_id=template.trainer.id,
workout_id=workout.id)
rating = put(cls(
user=user,
workout=workout,
trainer_rating=trainer_rating,
rating=rating)) # rating here is an integer (Rating.rating)
return rating