SQLAlchemy как объединять запросы - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь создать базу данных для шахматной лиги, которую пытаюсь создать.

Я написал нижеприведенный запрос, который дает мне желаемый результат, но он выглядит очень многословно, и я быкак второе мнение о том, как это можно написать лучше.

У меня есть две таблицы, одна представляет команду, а другая - «доску».Доска содержит результаты для каждого игрока и номер доски, на которой они играли.

class Board(db.Model):
    __tablename__ = 'board'
    id = db.Column(db.Integer, primary_key=True)
    board_number = db.Column(db.Integer)
    team_id = db.Column(db.Integer, db.ForeignKey("team.id"))
    result = db.Column(db.Float)

class Team(db.Model):
    __tablename__ = 'team'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    boards = db.relationship('Board', backref='teams', lazy=True)

Итак, для расчета таблицы лиги я создал 4 разных запроса: выигрыши, проигрыши, ничьи и общее количество очков.

Затем они объединяются и упорядочиваются по общему количеству баллов для создания таблицы лиги.

    wins = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('win')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=1)
    .group_by(Team.id)
    .subquery()
)



losses = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('loss')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=0)
    .group_by(Team.id)
    .subquery()
)


draws = (
    db.session.query(Team.id,
                     db.func.count(Board.result).label('draw')
                     )
    .filter(Team.league_id == 1)
    .join(Board).filter_by(team_id=Team.id, result=0.5)
    .group_by(Team.id)
    .subquery()
)

total_points = (
    db.session.query(Team.id,
                     db.func.sum(Board.result).label('total')
                     )
    .filter(Team.league_id == 1)
    .join(Board, (Board.team_id == Team.id))
    .group_by(Team.id)
    .subquery()
)


league_table = (
    db.session.query(Team.name, wins.c.win, draws.c.draw, losses.c.loss, total_points.c.total)
    .join((wins, wins.c.id == Team.id))
    .join((losses, losses.c.id == Team.id))
    .join((draws, draws.c.id == Team.id))
    .join((total_points, total_points.c.id == Team.id))
    .order_by((total_points.c.total).desc())
    .all()
)

Можно ли объединить 4 запроса в один?

1 Ответ

0 голосов
/ 04 марта 2019

Запросы могут быть выполнены в одном запросе с использованием агрегатного предложения FILTER:

Если указано FILTER, то только входные строки, для которых filter_clause оценивается как trueпередаются в статистическую функцию;

В SQLAlchemy вы можете использовать FunctionElement.filter() для создания предложения:

db.session.query(
        Team.name,
        db.func.count(Board.result).filter(Board.result == 1).label('win'),
        db.func.count(Board.result).filter(Board.result == 0).label('loss'),
        db.func.count(Board.result).filter(Board.result == 0.5).label('draw'),
        db.func.sum(Board.result).label('total'))\
    .join(Board)\
    .filter(Team.league_id == 1)\
    .group_by(Team.id)\
    .order_by(db.func.sum(Board.result).desc())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...