Refactor repositories
This commit is contained in:
parent
73d92645ca
commit
90242d770d
8 changed files with 114 additions and 134 deletions
|
@ -1,85 +0,0 @@
|
|||
from sqlalchemy import create_engine, insert, select
|
||||
from sqlalchemy.engine.base import Engine
|
||||
from datetime import date
|
||||
from dbapi.tables import training, exercise, approach
|
||||
|
||||
|
||||
class DatabaseInterfasesMixin:
|
||||
"""Mixin for interfaces, that works with database"""
|
||||
|
||||
def __init__(self, engine: Engine) -> None:
|
||||
self.engine: Engine = engine
|
||||
|
||||
|
||||
class TrainingRepository(DatabaseInterfasesMixin):
|
||||
"""Training table repository"""
|
||||
|
||||
def create_training(self, date: date) -> int:
|
||||
"""Method for creating new instance of training
|
||||
Args:
|
||||
date: date of a training
|
||||
|
||||
Returns:
|
||||
Primary key of created training entry
|
||||
"""
|
||||
new_instance_statement = insert(training).values(Date=date)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inerted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inerted_entry_pk
|
||||
|
||||
|
||||
class ExerciseRepository(DatabaseInterfasesMixin):
|
||||
"""Exercise table repository"""
|
||||
|
||||
def create_exercise(self, training_pk: int, exercise_name: str) -> int:
|
||||
"""Method for creating new instance of exercise table
|
||||
Args:
|
||||
training_pk: Primary key of associated training instance
|
||||
exercise_name: Name of an exercise
|
||||
|
||||
Returns:
|
||||
Primary key of created exercise entry
|
||||
"""
|
||||
new_instance_statement = insert(exercise).values(
|
||||
Training=training_pk, Name=exercise_name
|
||||
)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inserted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inserted_entry_pk
|
||||
|
||||
def get_exercises_from_training(self, training_pk: int):
|
||||
"""Method for getting rows of exercises, linked to training by its PK
|
||||
|
||||
Args:
|
||||
training_pk: Training table primary key
|
||||
"""
|
||||
statement = select(exercise).where(exercise.c.Training == training_pk)
|
||||
print(f"Exercises SQL statement: {statement}")
|
||||
|
||||
|
||||
class ApproachRepository(DatabaseInterfasesMixin):
|
||||
"""Approach table repository"""
|
||||
|
||||
def create_approach(self, exercise_pk: int, weight: float, reps: int) -> int:
|
||||
"""Method for creating new instance of approach table
|
||||
|
||||
Args:
|
||||
exercise_pk: Primary key of an associated exercise
|
||||
weight: Approach weight
|
||||
reps: Amount of reps in approach
|
||||
|
||||
Returns:
|
||||
Primary key of created exercise entry
|
||||
"""
|
||||
new_instance_statement = insert(approach).values(
|
||||
Exercise=exercise_pk, Weight=weight, Reps=reps
|
||||
)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inserted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inserted_entry_pk
|
0
dbapi/repositories/__init__.py
Normal file
0
dbapi/repositories/__init__.py
Normal file
27
dbapi/repositories/approach_repo.py
Normal file
27
dbapi/repositories/approach_repo.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
from dbapi.repositories.utils import DatabaseInterfasesMixin
|
||||
from sqlalchemy import insert
|
||||
from dbapi.tables import approach
|
||||
|
||||
|
||||
class ApproachRepository(DatabaseInterfasesMixin):
|
||||
"""Approach table repository"""
|
||||
|
||||
def create_approach(self, exercise_pk: int, weight: float, reps: int) -> int:
|
||||
"""Method for creating new instance of approach table
|
||||
|
||||
Args:
|
||||
exercise_pk: Primary key of an associated exercise
|
||||
weight: Approach weight
|
||||
reps: Amount of reps in approach
|
||||
|
||||
Returns:
|
||||
Primary key of created exercise entry
|
||||
"""
|
||||
new_instance_statement = insert(approach).values(
|
||||
Exercise=exercise_pk, Weight=weight, Reps=reps
|
||||
)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inserted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inserted_entry_pk
|
25
dbapi/repositories/exercise_repo.py
Normal file
25
dbapi/repositories/exercise_repo.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from sqlalchemy import insert
|
||||
from dbapi.repositories.utils import DatabaseInterfasesMixin
|
||||
from dbapi.tables import exercise
|
||||
|
||||
|
||||
class ExerciseRepository(DatabaseInterfasesMixin):
|
||||
"""Exercise table repository"""
|
||||
|
||||
def create_exercise(self, training_pk: int, exercise_name: str) -> int:
|
||||
"""Method for creating new instance of exercise table
|
||||
Args:
|
||||
training_pk: Primary key of associated training instance
|
||||
exercise_name: Name of an exercise
|
||||
|
||||
Returns:
|
||||
Primary key of created exercise entry
|
||||
"""
|
||||
new_instance_statement = insert(exercise).values(
|
||||
Training=training_pk, Name=exercise_name
|
||||
)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inserted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inserted_entry_pk
|
23
dbapi/repositories/training_repo.py
Normal file
23
dbapi/repositories/training_repo.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from sqlalchemy import insert
|
||||
from datetime import date
|
||||
from dbapi.repositories.utils import DatabaseInterfasesMixin
|
||||
from dbapi.tables import training
|
||||
|
||||
|
||||
class TrainingRepository(DatabaseInterfasesMixin):
|
||||
"""Training table repository"""
|
||||
|
||||
def create_training(self, date: date) -> int:
|
||||
"""Method for creating new instance of training
|
||||
Args:
|
||||
date: date of a training
|
||||
|
||||
Returns:
|
||||
Primary key of created training entry
|
||||
"""
|
||||
new_instance_statement = insert(training).values(Date=date)
|
||||
with self.engine.connect() as conn:
|
||||
result = conn.execute(new_instance_statement)
|
||||
inerted_entry_pk: int = result.inserted_primary_key[0]
|
||||
conn.commit()
|
||||
return inerted_entry_pk
|
8
dbapi/repositories/utils.py
Normal file
8
dbapi/repositories/utils.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from sqlalchemy import Engine
|
||||
|
||||
|
||||
class DatabaseInterfasesMixin:
|
||||
"""Mixin for interfaces, that works with database"""
|
||||
|
||||
def __init__(self, engine: Engine) -> None:
|
||||
self.engine: Engine = engine
|
59
main.py
59
main.py
|
@ -7,11 +7,9 @@ from sqlalchemy import Table, create_engine, text, insert
|
|||
from dotenv import load_dotenv
|
||||
from sqlalchemy.ext.asyncio import create_async_engine
|
||||
from dbapi.migrator import FitnessDatabseMigrator
|
||||
from dbapi.repositories import (
|
||||
ApproachRepository,
|
||||
ExerciseRepository,
|
||||
TrainingRepository,
|
||||
)
|
||||
from dbapi.repositories.approach_repo import ApproachRepository
|
||||
from dbapi.repositories.exercise_repo import ExerciseRepository
|
||||
from dbapi.repositories.training_repo import TrainingRepository
|
||||
from dbapi.tables import metadata_obj, training, exercise, approach
|
||||
from obsidian.notes_parser import parse_training_data, remap_unique_exercises
|
||||
from apple.notes_parser import parse_training_data as apple_parse_training_data
|
||||
|
@ -58,8 +56,8 @@ async_engine = create_async_engine(
|
|||
# TODO: Check how migrations are done
|
||||
|
||||
# NOTE: Drop all Tables from database
|
||||
# metadata_obj.drop_all(engine)
|
||||
# metadata_obj.create_all(engine)
|
||||
metadata_obj.drop_all(engine)
|
||||
metadata_obj.create_all(engine)
|
||||
|
||||
# NOTE: Table reflection - generating table object from existing tables (only tables, that are stored in metadata)
|
||||
# some_table = Table("some_table", metadata_obj, autoload_with=engine)
|
||||
|
@ -69,27 +67,26 @@ async_engine = create_async_engine(
|
|||
|
||||
# Inserting training values into database
|
||||
|
||||
# trainings: List[Training] = parse_training_data()
|
||||
# for train in trainings:
|
||||
# if not train:
|
||||
# continue
|
||||
# else:
|
||||
# print(train)
|
||||
# new_training_pk: int = TrainingRepository(engine).create_training(train.date)
|
||||
# for exr in train.exercises:
|
||||
# approach_statements = []
|
||||
# new_exercise_pk: int = ExerciseRepository(engine).create_exercise(
|
||||
# training_pk=new_training_pk, exercise_name=exr.name
|
||||
# )
|
||||
# for appr in exr.approaches:
|
||||
# new_approach_pk: int = ApproachRepository(engine).create_approach(
|
||||
# exercise_pk=new_exercise_pk, weight=appr.weight, reps=appr.reps
|
||||
# )
|
||||
#
|
||||
#
|
||||
# print("-------------------------\n" * 2)
|
||||
# print("-------------------------\n" * 2)
|
||||
# ExerciseRepository(engine=engine).get_exercises_from_training(1)
|
||||
trainings: List[Training] = parse_training_data()
|
||||
for train in trainings:
|
||||
if not train:
|
||||
continue
|
||||
else:
|
||||
print(train)
|
||||
new_training_pk: int = TrainingRepository(engine).create_training(train.date)
|
||||
for exr in train.exercises:
|
||||
approach_statements = []
|
||||
new_exercise_pk: int = ExerciseRepository(engine).create_exercise(
|
||||
training_pk=new_training_pk, exercise_name=exr.name
|
||||
)
|
||||
for appr in exr.approaches:
|
||||
new_approach_pk: int = ApproachRepository(engine).create_approach(
|
||||
exercise_pk=new_exercise_pk, weight=appr.weight, reps=appr.reps
|
||||
)
|
||||
|
||||
|
||||
print("-------------------------\n" * 2)
|
||||
print("-------------------------\n" * 2)
|
||||
# -----
|
||||
|
||||
# Calculating unique exercises for obsidian
|
||||
|
@ -185,6 +182,8 @@ async_engine = create_async_engine(
|
|||
# pprint(unique_exercise_parsed_names)
|
||||
# print(len(combined_trainings))
|
||||
|
||||
fbm = FitnessDatabseMigrator(async_engine=async_engine)
|
||||
# Async engine playground
|
||||
|
||||
asyncio.run(fbm.reset_database())
|
||||
# fbm = FitnessDatabseMigrator(async_engine=async_engine)
|
||||
#
|
||||
# asyncio.run(fbm.reset_database())
|
||||
|
|
21
poetry.lock
generated
21
poetry.lock
generated
|
@ -1,10 +1,9 @@
|
|||
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
description = "Reusable constraint types to use with typing.Annotated"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -16,7 +15,6 @@ files = [
|
|||
name = "async-timeout"
|
||||
version = "5.0.1"
|
||||
description = "Timeout context manager for asyncio programs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -28,7 +26,6 @@ files = [
|
|||
name = "asyncpg"
|
||||
version = "0.30.0"
|
||||
description = "An asyncio PostgreSQL driver"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
|
@ -95,7 +92,6 @@ test = ["distro (>=1.9.0,<1.10.0)", "flake8 (>=6.1,<7.0)", "flake8-pyi (>=24.1.0
|
|||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
|
@ -107,7 +103,6 @@ files = [
|
|||
name = "exceptiongroup"
|
||||
version = "1.2.2"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -122,7 +117,6 @@ test = ["pytest (>=6)"]
|
|||
name = "greenlet"
|
||||
version = "3.1.1"
|
||||
description = "Lightweight in-process concurrent programming"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -209,7 +203,6 @@ test = ["objgraph", "psutil"]
|
|||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -221,7 +214,6 @@ files = [
|
|||
name = "packaging"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -233,7 +225,6 @@ files = [
|
|||
name = "pluggy"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -249,7 +240,6 @@ testing = ["pytest", "pytest-benchmark"]
|
|||
name = "psycopg2"
|
||||
version = "2.9.10"
|
||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -269,7 +259,6 @@ files = [
|
|||
name = "pydantic"
|
||||
version = "2.10.5"
|
||||
description = "Data validation using Python type hints"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -290,7 +279,6 @@ timezone = ["tzdata"]
|
|||
name = "pydantic-core"
|
||||
version = "2.27.2"
|
||||
description = "Core functionality for Pydantic validation and serialization"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -403,7 +391,6 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
|||
name = "pytest"
|
||||
version = "8.3.4"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -426,7 +413,6 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments
|
|||
name = "python-dotenv"
|
||||
version = "1.0.1"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -441,7 +427,6 @@ cli = ["click (>=5.0)"]
|
|||
name = "sqlalchemy"
|
||||
version = "2.0.37"
|
||||
description = "Database Abstraction Library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -505,7 +490,7 @@ files = [
|
|||
]
|
||||
|
||||
[package.dependencies]
|
||||
greenlet = {version = "!=0.4.17", markers = "python_version < \"3.14\" and platform_machine == \"aarch64\" or python_version < \"3.14\" and platform_machine == \"ppc64le\" or python_version < \"3.14\" and platform_machine == \"x86_64\" or python_version < \"3.14\" and platform_machine == \"amd64\" or python_version < \"3.14\" and platform_machine == \"AMD64\" or python_version < \"3.14\" and platform_machine == \"win32\" or python_version < \"3.14\" and platform_machine == \"WIN32\""}
|
||||
greenlet = {version = "!=0.4.17", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"}
|
||||
typing-extensions = ">=4.6.0"
|
||||
|
||||
[package.extras]
|
||||
|
@ -537,7 +522,6 @@ sqlcipher = ["sqlcipher3_binary"]
|
|||
name = "tomli"
|
||||
version = "2.2.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -579,7 +563,6 @@ files = [
|
|||
name = "typing-extensions"
|
||||
version = "4.12.2"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
|
Loading…
Reference in a new issue