Move all files into agon module.

This commit is contained in:
2025-03-19 09:07:39 -04:00
parent a46dc0388c
commit 17769022bc
29 changed files with 0 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
"""Package for database interaction."""
+40
View File
@@ -0,0 +1,40 @@
import os
from dotenv import load_dotenv
from sqlmodel import Session, SQLModel, create_engine, select
from models import CategoryGroup, Guild
load_dotenv()
SQL_DB = os.getenv("SQL_DB", "")
SQL_HOST = os.getenv("SQL_HOST", "")
SQL_PASS = os.getenv("SQL_PASS", "")
SQL_USER = os.getenv("SQL_USER", "")
url = "sqlite:///database.db"
# url = f"mysql+pymysql://{SQL_USER}:{SQL_PASS}@{SQL_HOST}/{SQL_DB}"
engine = create_engine(url)
SQLModel.metadata.create_all(engine)
with Session(engine) as session:
guild = Guild(id=1, name="test guild")
session.add(guild)
group1 = CategoryGroup(name="group1", channel_id=1, guild_id=1, message_id=1)
group2 = CategoryGroup(name="group2", channel_id=2, guild_id=1, message_id=2)
session.add(group1)
session.add(group2)
session.commit()
# anotherone = Guild(id=2, name="test guild 2", submission_channel=1, verification_channel=2)
# session.add(anotherone)
# group1 = CategoryGroup(name="group1", channel_id=1, guild_id=2, message_id=1)
# group2 = CategoryGroup(name="group2", channel_id=2, guild_id=2, message_id=2)
# session.add(group1)
# session.add(group2)
# session.commit()
stmt = select(Guild).where(Guild.name == "Dakiny")
guild = session.scalar(stmt)
print(guild.category_groups)
+18
View File
@@ -0,0 +1,18 @@
"""Simple file to set up the sqlmodel connection to database."""
from sqlmodel import SQLModel, create_engine
from utilities import config
from utilities.logger import agon_logger
from . import models # noqa: F401 - Need this import for creating the models.
if config.ENVIRONMENT == "prod":
url = f"mysql+pymysql://{config.SQL_USER}:{config.SQL_PASS}@{config.SQL_HOST}/{config.SQL_DB}"
agon_logger.info("Connected to prod database.")
else:
url = "sqlite:///database.db"
agon_logger.info("Connected to local dev database.")
engine = create_engine(url)
# Don't need to create all when connected to prod.
SQLModel.metadata.create_all(engine)
+186
View File
@@ -0,0 +1,186 @@
"""File holds all model definitions of SQL tables."""
from sqlalchemy.dialects.mysql import BIGINT, BOOLEAN, FLOAT, INTEGER, SMALLINT, VARCHAR
from sqlmodel import Column, Field, ForeignKey, Relationship, SQLModel, UniqueConstraint
class Guild(SQLModel, table=True):
"""
Represents a Guild entity in the database.
Attributes:
id (int): The unique identifier for the guild.
name (str): The name of the guild.
submission_channel (int): The ID of the submission channel associated with the guild.
verification_channel (int): The ID of the verification channel associated with the guild.
active (bool): Indicates whether the guild is active. Defaults to True.
category_groups (list[CategoryGroup]): A list of category groups associated with the guild.
"""
__tablename__: str = "Guilds"
id: int = Field(sa_column=Column("GuildId", BIGINT(unsigned=True), primary_key=True, nullable=False))
name: str = Field(sa_column=Column("GuildName", VARCHAR), max_length=95)
# deprecated, not currently used.
submission_channel: int | None = Field(
sa_column=Column("SubmissionChannel", BIGINT(unsigned=True), nullable=True), default=None
)
verification_channel: int | None = Field(
sa_column=Column("VerificationChannel", BIGINT(unsigned=True), nullable=True), default=None
)
active: bool = Field(sa_column=Column("Active", BOOLEAN), default=True)
category_groups: list["CategoryGroup"] = Relationship(back_populates="guild", cascade_delete=True)
class CategoryGroup(SQLModel, table=True):
"""
Represents a category group in the database.
Attributes:
id (int | None): The primary key of the category group.
name (str): The name of the category group, with a maximum length of 50 characters.
channel_id (int): The ID of the channel associated with the category group.
guild_id (int): The ID of the guild associated with the category group.
message_id (int): The ID of the message associated with the category group.
pad_length (int): The padding length for the category group, default is 12.
username_length (int): The username length for the category group, default is 12.
guild (Guild | None): The guild relationship back-populated from the Guild model.
Table Constraints:
__table_args__: Unique constraint on guild_id and name to ensure unique category groups within a guild.
"""
__tablename__: str = "CategoryGroups"
id: int | None = Field(sa_column=Column("GroupId", INTEGER, primary_key=True), default=None)
name: str = Field(sa_column=Column("GroupName", VARCHAR), max_length=50)
channel_id: int = Field(sa_column=Column("ChannelId", BIGINT(unsigned=True)))
guild_id: int = Field(
sa_column=Column(
"GuildId",
BIGINT(unsigned=True),
ForeignKey("Guilds.GuildId", ondelete="CASCADE"),
nullable=False,
)
)
message_id: int | None = Field(sa_column=Column("MessageId", BIGINT(unsigned=True)), default=None)
pad_length: int = Field(default=12, sa_column=Column("PadLength", SMALLINT(unsigned=True)))
username_length: int = Field(default=12, sa_column=Column("UsernameLength", SMALLINT(unsigned=True)))
__table_args__ = (UniqueConstraint("GuildId", "GroupName", name="UniqueGuildCategoryGroup"),)
guild: Guild | None = Relationship(back_populates="category_groups")
categories: list["Category"] | None = Relationship(back_populates="category_group", cascade_delete=True)
class Category(SQLModel, table=True):
"""
Represents a category in the database.
Attributes:
id (int): The unique identifier for the category. Primary key.
name (str): The name of the category with a maximum length of 30 characters.
group_id (int): The identifier of the group to which the category belongs.
Foreign key referencing CategoryGroups.id.
size (int): The size attribute of the category, default is 3.
is_ascending (bool): Indicates if the category is in ascending order. Default is True.
is_time_record (bool): Indicates if the category is a time record. Default is False.
is_validated (bool): Indicates if the category is validated. Default is True.
category_group (CategoryGroup | None): The relationship to the CategoryGroup model.
scores (list["Score"] | None): The relationship to the Score model with cascade delete enabled.
Table Constraints:
__table_args__: Unique constraint on group_id and name to ensure unique category names within a group.
"""
__tablename__: str = "Categories"
id: int = Field(sa_column=Column("CategoryId", INTEGER, primary_key=True), default=None)
name: str = Field(sa_column=Column("CategoryName", VARCHAR), max_length=30)
group_id: int = Field(
sa_column=Column(
"GroupId",
INTEGER(unsigned=True),
ForeignKey("CategoryGroups.GroupId", ondelete="CASCADE"),
nullable=False,
)
)
size: int = Field(sa_column=Column("Size", SMALLINT(unsigned=True), nullable=False), default=3)
is_ascending: bool = Field(sa_column=Column("IsAscending", BOOLEAN, nullable=False), default=True)
is_time_record: bool = Field(sa_column=Column("IsTimeRecord", BOOLEAN, nullable=False), default=False)
is_validated: bool = Field(sa_column=Column("IsValidated", BOOLEAN, nullable=False), default=True)
__table_args__ = (UniqueConstraint("GroupId", "CategoryName", name="UniqueCategoryInGroup"),)
category_group: CategoryGroup | None = Relationship(back_populates="categories")
scores: list["Score"] | None = Relationship(back_populates="category", cascade_delete=True)
class Score(SQLModel, table=True):
"""
Represents a score entry in the database.
Attributes:
username (str): The username associated with the score. This is a primary key.
score (float): The score value.
category_id (int): The ID of the category this score belongs to. This is a primary key and a foreign key
referencing the Categories table.
category (Category | None): The relationship to the Category model, back-populated by the scores attribute
in the Category model.
"""
__tablename__: str = "Scores"
username: str = Field(sa_column=Column("UserName", VARCHAR, primary_key=True, nullable=False), max_length=30)
score: float = Field(sa_column=Column("Score", FLOAT, nullable=False))
category_id: int = Field(
sa_column=Column(
"CategoryId",
INTEGER(unsigned=True),
ForeignKey("Categories.CategoryId", ondelete="CASCADE"),
nullable=False,
primary_key=True,
),
)
category: Category | None = Relationship(back_populates="scores")
class Submission(SQLModel, table=True):
"""
Represents a submission in the database.
Attributes:
category_id (int): The ID of the category. This is a primary key.
group_id (int): The ID of the group.
guild_id (int): The ID of the guild.
message_id (int): The ID of the message.
score (str): The score of the submission, with a maximum length of 30 characters.
user_id (int): The ID of the user.
username (str): The username of the user. This is a primary key.
"""
__tablename__: str = "Submissions"
category_id: int = Field(
sa_column=Column(
"CategoryId",
INTEGER(unsigned=True),
nullable=False,
primary_key=True,
),
)
group_id: int = Field(
sa_column=Column(
"GroupId",
INTEGER(unsigned=True),
nullable=False,
)
)
guild_id: int = Field(sa_column=Column("GuildId", BIGINT(unsigned=True), nullable=False))
message_id: int = Field(sa_column=Column("MessageId", BIGINT(unsigned=True), nullable=False))
# Score is stored as a string until converted during submission.
score: str = Field(sa_column=Column("Score", VARCHAR, nullable=False), max_length=30)
user_id: int = Field(sa_column=Column("UserId", BIGINT(unsigned=True), nullable=False))
username: str = Field(sa_column=Column("UserName", VARCHAR, nullable=False, primary_key=True), max_length=30)