#python #sqlalchemy
#python #sqlalchemy
Вопрос:
Я создаю приложение на python, в котором есть база данных с результатами разных футбольных матчей.
Я хочу, чтобы модель устанавливала свое result
поле на основе значений полей home_score
и away_score
.
Я много работал с Django, но не в этот раз, поскольку это будет простое приложение терминала. Если бы я был, я бы save
подклассировал метод с помощью некоторого кода в приведенном result
ниже методе.
Будучи несколько новичком в SQLAlchemy, я предположил, что @hybrid_property
декоратор был хорошим прокси для того, чего я пытался достичь.
Однако, когда я запускаю свои unittests для этой модели, он завершается ошибкой в следующей строке elif self.home_score > self.away_score:
со следующей ошибкой:
TypeError: Boolean value of this clause is not defined
Я включил модель ниже, кто-нибудь знает, что я делаю неправильно?
class Match(Base):
__tablename__ = 'matches'
id = Column(Integer, primary_key=True)
date = Column(Date, nullable=False)
home_id = Column(Integer, ForeignKey('teams.id'))
home = relationship(
"Team", back_populates='home_matches', foreign_keys=[home_id]
)
away_id = Column(Integer, ForeignKey('teams.id'))
away = relationship(
"Team", back_populates='away_matches', foreign_keys=[away_id]
)
home_score = Column(Integer, nullable=False)
away_score = Column(Integer, nullable=False)
@hybrid_property
def result(self):
""" Set the match result, based on the team scores """
if self.home_score == self.away_score:
return 'draw'
elif self.home_score > self.away_score:
return 'home'
elif self.home_score < self.away_score:
return 'away'
Комментарии:
1. Завершаются ли тесты для остальных условий также неудачно?
Ответ №1:
Идея гибридного свойства заключается в создании эквивалентного SQL при использовании в контексте запроса. Для некоторых простых выражений один и тот же код работает для обоих, но если нет, вы должны определить выражение отдельно. В этом случае вы можете заменить свой Python CASE
выражением SQL:
from sqlalchemy import case
...
@hybrid_property
def result(self):
""" Set the match result, based on the team scores """
if self.home_score == self.away_score:
return 'draw'
elif self.home_score > self.away_score:
return 'home'
elif self.home_score < self.away_score:
return 'away'
@result.expression
def result(cls):
""" Set the match result, based on the team scores """
return case([(cls.home_score == cls.away_score, 'draw'),
(cls.home_score > cls.away_score, 'home')],
else_='away')
Комментарии:
1. Спасибо за ответ! К сожалению, когда я пробую этот код, он завершается
AttributeError: can't set attribute
ошибкой. (Хотя, конечно, возможно, что проблема здесь в моем собственном коде, я рассмотрю это!)2. Невозможно воспроизвести, поэтому я склонен сказать, что ошибка в другом месте.
3. @Jasper вы заставили это работать — сейчас я сталкиваюсь с той же проблемой с AttributeError