Skip to main content

Overview

The GameStats model stores comprehensive match statistics for a team’s performance in a specific game. It includes advanced metrics such as expected goals (xG), passing statistics, defensive actions, possession data, and goalkeeping stats. Each game typically has two GameStats records (one per team).

Model Definition

Table Name: game_stats Location: premier_league/data/models/game_stats.py:7

Primary Fields

id
Integer
required
Auto-incrementing primary key for the game stats record.
game_id
String
required
Foreign key reference to the game. Links to game.id.
team_id
String
required
Foreign key reference to the team. Links to team.id.

Relationships

game
Game
SQLAlchemy relationship to the Game object. Configured with uselist=False to return a single game object.
team
Team
SQLAlchemy relationship to the Team object that these statistics belong to.

Expected Goals and Assists

xG
Float
Expected goals - a measure of the quality of chances created by the team.
xA
Float
Expected assists - a measure of the quality of goal-scoring opportunities created for teammates.
xAG
Float
Expected assisted goals - combines xG and xA for an overall attacking threat metric.

Shots Statistics

All shot statistics are broken down by position (FW=Forward, MF=Midfielder, DF=Defender):
shots_total_FW
Integer
Total shots taken by forwards.
shots_total_MF
Integer
Total shots taken by midfielders.
shots_total_DF
Integer
Total shots taken by defenders.
shots_on_target_FW
Integer
Shots on target by forwards.
shots_on_target_MF
Integer
Shots on target by midfielders.
shots_on_target_DF
Integer
Shots on target by defenders.

Chance Creation

shot_creating_chances_FW
Integer
Actions by forwards that lead to a shot (pass, dribble, foul drawn, etc.).
shot_creating_chances_MF
Integer
Actions by midfielders that lead to a shot.
shot_creating_chances_DF
Integer
Actions by defenders that lead to a shot.
goal_creating_actions_FW
Integer
Actions by forwards that directly lead to a goal.
goal_creating_actions_MF
Integer
Actions by midfielders that directly lead to a goal.
goal_creating_actions_DF
Integer
Actions by defenders that directly lead to a goal.

Passing Statistics

passes_completed_FW
Integer
Successful passes completed by forwards.
passes_completed_MF
Integer
Successful passes completed by midfielders.
passes_completed_DF
Integer
Successful passes completed by defenders.
pass_completion_percentage_FW
Float
Pass completion percentage for forwards.
pass_completion_percentage_MF
Float
Pass completion percentage for midfielders.
pass_completion_percentage_DF
Float
Pass completion percentage for defenders.
key_passes
Integer
Passes that directly lead to a shot.
passes_into_final_third
Integer
Completed passes into the attacking third of the pitch.
passes_into_penalty_area
Integer
Completed passes into the opponent’s penalty area.
crosses_into_penalty_area
Integer
Crosses completed into the opponent’s penalty area.
progressive_passes
Integer
Passes that move the ball significantly closer to the opponent’s goal.

Defensive Statistics

tackles_won_FW
Integer
Successful tackles by forwards.
tackles_won_MF
Integer
Successful tackles by midfielders.
tackles_won_DF
Integer
Successful tackles by defenders.
dribblers_challenged_won_FW
Integer
Successful challenges against dribbling opponents by forwards.
dribblers_challenged_won_MF
Integer
Successful challenges against dribbling opponents by midfielders.
dribblers_challenged_won_DF
Integer
Successful challenges against dribbling opponents by defenders.
blocks_FW
Integer
Blocked shots or passes by forwards.
blocks_MF
Integer
Blocked shots or passes by midfielders.
blocks_DF
Integer
Blocked shots or passes by defenders.
interceptions_FW
Integer
Interceptions by forwards.
interceptions_MF
Integer
Interceptions by midfielders.
interceptions_DF
Integer
Interceptions by defenders.
clearances_FW
Integer
Clearances by forwards.
clearances_MF
Integer
Clearances by midfielders.
clearances_DF
Integer
Clearances by defenders.
errors_leading_to_goal
Integer
Defensive errors that directly resulted in an opponent’s goal.

Possession Statistics

possession_rate
Integer
Ball possession percentage (0-100).
touches_FW
Integer
Total ball touches by forwards.
touches_MF
Integer
Total ball touches by midfielders.
touches_DF
Integer
Total ball touches by defenders.
touches_att_pen_area_FW
Integer
Touches in the attacking penalty area by forwards.
touches_att_pen_area_MF
Integer
Touches in the attacking penalty area by midfielders.
touches_att_pen_area_DF
Integer
Touches in the attacking penalty area by defenders.
take_ons_FW
Integer
Attempted dribbles/take-ons by forwards.
take_ons_MF
Integer
Attempted dribbles/take-ons by midfielders.
take_ons_DF
Integer
Attempted dribbles/take-ons by defenders.
successful_take_ons_FW
Integer
Successful dribbles/take-ons by forwards.
successful_take_ons_MF
Integer
Successful dribbles/take-ons by midfielders.
successful_take_ons_DF
Integer
Successful dribbles/take-ons by defenders.
carries_FW
Integer
Number of times forwards carried the ball.
carries_MF
Integer
Number of times midfielders carried the ball.
carries_DF
Integer
Number of times defenders carried the ball.
carries_into_penalty_area
Integer
Ball carries that entered the opponent’s penalty area.
total_carrying_distance_FW
Integer
Total distance (in yards) the ball was carried by forwards.
total_carrying_distance_MF
Integer
Total distance (in yards) the ball was carried by midfielders.
total_carrying_distance_DF
Integer
Total distance (in yards) the ball was carried by defenders.
dispossessed_FW
Integer
Times forwards lost possession to an opponent.
dispossessed_MF
Integer
Times midfielders lost possession to an opponent.
dispossessed_DF
Integer
Times defenders lost possession to an opponent.
aerials_won_FW
Integer
Aerial duels won by forwards.
aerials_won_MF
Integer
Aerial duels won by midfielders.
aerials_won_DF
Integer
Aerial duels won by defenders.
aerials_lost_FW
Integer
Aerial duels lost by forwards.
aerials_lost_MF
Integer
Aerial duels lost by midfielders.
aerials_lost_DF
Integer
Aerial duels lost by defenders.
miss_controlled_FW
Integer
Poor ball controls by forwards.
miss_controlled_MF
Integer
Poor ball controls by midfielders.
miss_controlled_DF
Integer
Poor ball controls by defenders.

Goalkeeping Statistics

save_percentage
Float
Percentage of shots on target that were saved by the goalkeeper.
saves
Integer
Total number of saves made by the goalkeeper.
PSxG
Float
Post-shot expected goals - quality of shots faced by the goalkeeper.
passes_completed_GK
Integer
Successful passes completed by the goalkeeper.
crosses_stopped
Integer
Crosses into the box stopped by the goalkeeper.
passes_40_yard_completed_GK
Integer
Long passes (40+ yards) completed by the goalkeeper.

Other Match Statistics

yellow_card
Integer
Number of yellow cards received.
red_card
Integer
Number of red cards received.
pens_won
Integer
Penalties won by the team.
pens_conceded
Integer
Penalties conceded by the team.
fouls_committed_FW
Integer
Fouls committed by forwards.
fouls_committed_MF
Integer
Fouls committed by midfielders.
fouls_committed_DF
Integer
Fouls committed by defenders.
fouls_drawn_FW
Integer
Fouls drawn by forwards.
fouls_drawn_MF
Integer
Fouls drawn by midfielders.
fouls_drawn_DF
Integer
Fouls drawn by defenders.
offside_FW
Integer
Offside calls against forwards.
offside_MF
Integer
Offside calls against midfielders.
offside_DF
Integer
Offside calls against defenders.

Database Indexes

The GameStats model includes a unique composite index:
  • idx_game_team_stats: Unique composite index on (game_id, team_id) ensuring each team has only one stats record per game

Methods

to_dict()

def to_dict(self) -> dict:
Converts the GameStats model instance to a dictionary representation. Returns:
  • dict: Dictionary containing all statistics fields.
Example Output:
{
  "id": 1,
  "game_id": "game_12345",
  "team_id": "team_arsenal",
  "xG": 2.3,
  "xA": 1.8,
  "xAG": 4.1,
  "shots_total_FW": 8,
  "shots_total_MF": 5,
  "shots_total_DF": 2,
  "shots_on_target_FW": 4,
  "shots_on_target_MF": 2,
  "shots_on_target_DF": 1,
  "possession_rate": 58,
  "passes_completed_FW": 120,
  "passes_completed_MF": 280,
  "passes_completed_DF": 195,
  "key_passes": 12,
  "tackles_won_DF": 8,
  "yellow_card": 2,
  "red_card": 0
}

Usage Examples

Querying Game Statistics

from sqlalchemy.orm import Session
from premier_league.data.models import GameStats

# Get stats for a specific team in a game
stats = session.query(GameStats).filter(
    GameStats.game_id == "game_12345",
    GameStats.team_id == "team_arsenal"
).first()

# Get all stats for a specific game
game_stats = session.query(GameStats).filter(
    GameStats.game_id == "game_12345"
).all()

for stats in game_stats:
    print(f"Team {stats.team_id}: xG={stats.xG}, possession={stats.possession_rate}%")

# Find high xG performances
high_xg = session.query(GameStats).filter(
    GameStats.xG > 3.0
).order_by(GameStats.xG.desc()).all()

Accessing Relationships

# Access related game and team data
stats = session.query(GameStats).filter(GameStats.id == 1).first()

print(f"Game: {stats.game.home_team.name} vs {stats.game.away_team.name}")
print(f"Team: {stats.team.name}")
print(f"xG: {stats.xG}")
print(f"Possession: {stats.possession_rate}%")

Creating New Game Statistics

from premier_league.data.models import GameStats

new_stats = GameStats(
    game_id="game_12346",
    team_id="team_liverpool",
    xG=2.8,
    xA=1.5,
    xAG=4.3,
    shots_total_FW=10,
    shots_on_target_FW=6,
    possession_rate=62,
    passes_completed_FW=145,
    passes_completed_MF=320,
    passes_completed_DF=210,
    tackles_won_DF=12,
    yellow_card=1,
    red_card=0
)

session.add(new_stats)
session.commit()

Analyzing Team Performance

# Calculate average xG for a team across multiple games
from sqlalchemy import func

avg_xg = session.query(func.avg(GameStats.xG)).filter(
    GameStats.team_id == "team_arsenal"
).scalar()

print(f"Average xG: {avg_xg:.2f}")

# Find teams with high possession
high_possession = session.query(GameStats).filter(
    GameStats.possession_rate > 60
).join(GameStats.team).all()

for stats in high_possession:
    print(f"{stats.team.name}: {stats.possession_rate}% possession")
  • Game - The game these statistics belong to
  • Team - The team that recorded these statistics

Build docs developers (and LLMs) love