SQLAlchemy — ошибка типа: логическое значение этого предложения не определено

#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