From 3b9aa8150b808fb4ff6db4e5cd1357431417adc0 Mon Sep 17 00:00:00 2001 From: sherl Date: Tue, 3 Jun 2025 02:38:13 +0200 Subject: [PATCH] feat: new last_goal_for endpoint, simple_select_all improvements also introduces sample usage for the new endpoint in lewy_routes --- .../FlaskWebProject/lewy_api_v1.py | 14 +++++ FlaskWebProject/FlaskWebProject/lewy_db.py | 58 +++++++++++++++++-- .../FlaskWebProject/lewy_routes.py | 5 ++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py index efa0d63..7e71515 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py +++ b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py @@ -105,6 +105,20 @@ def debugger_halt(r): breakpoint() return 200, "ok", [] +def last_goal_for(sportowiec: str = "MVC8zHZD"): + """ + Pobierz klub, dla którego sportowiec (domyślnie Robert) oddał ostatni gol. + + :returns: Klub, lub None + :rtype: kluby | None + """ + + sportowiec = getDb().simple_select_all("sportowcy", zewnetrzne_id_zawodnika=sportowiec) + if sportowiec != []: + return sportowiec[0].ostatni_gol_dla + + return None + def lookup(data, request): """ Obsługuje zapytania zwrócone do /api/v1/... diff --git a/FlaskWebProject/FlaskWebProject/lewy_db.py b/FlaskWebProject/FlaskWebProject/lewy_db.py index df6e0d9..0b5c515 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_db.py +++ b/FlaskWebProject/FlaskWebProject/lewy_db.py @@ -6,6 +6,7 @@ from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, rela from typing import List import time import toml +import traceback global db @@ -167,18 +168,40 @@ class baza(): try: return_val = func(self, *args, **kwargs) except: + print( "\033[91m" + f"Wystąpił błąd podczas wykonywania zapytania SQL:" + "\033[0m" + "\n" + f"{traceback.format_exc()}") self.session.rollback() self.session.close() self.refresh_session() return return_val return wrapper + def str_to_column(self, string: str): + """ + Zamienia tekstowy zapis "tabela.kolumna" + na obiekt modelu bazy (ze zmiennej self.entities). + Zwraca None jeśli takowego nie znajdzie. + Zamiennik dla niepożądanego eval(). + + :param string: Zapis tekstowy + :type string: str + """ + table_str = string[:string.find('.')] + column_str = string[string.find('.') + 1:] + if hasattr(self.entities[table_str], column_str): + return getattr(self.entities[table_str], column_str) + return None + @exit_gracefully def simple_select_all(self, entity_type, **kwargs): """ Użycie: simple_select_all(ldb.sportowcy, zewnetrzne_id_zawodnika="MVC8zHZD") simple_select_all("sportowcy", id_zawodnika=1) + simple_select_all("kluby", ..., LIMIT=5, ORDER_BY="kluby.skrocona_nazwa") https://stackoverflow.com/a/75316945 Did they make it harder to query dynamically on purpose? ~Frank 19.11.2023 @@ -187,18 +210,45 @@ class baza(): if not isinstance(entity_type, str): entity_type = entity_type.__name__ + # Save special arguments received with kwargs, + # that are meant for SQL operations to special_args, + # and delete from the rest, that will be passed + # directly to filter_by(). + # They will not be passed as search query, but serve + # as an additional search parameter. + special_keywords = ("ORDER_BY", "ORDER_BY_DESC", "LIMIT") + special_args = {} + + for arg in special_keywords: + if arg in kwargs: + special_args[arg] = kwargs[arg] + del kwargs[arg] + print(f"[{round(time.time())}] SELECT") results = ( self.session. query(self.entities[entity_type]). - filter_by(**kwargs). - all() + filter_by(**kwargs) ) - print(f"[{round(time.time())}] SELECT RESULTS: {results}") + if "ORDER_BY" in special_args: + column = self.str_to_column(special_args["ORDER_BY"]) + if column is not None: + results = results.order_by(column) - return results + if "ORDER_BY_DESC" in special_args: + column = self.str_to_column(special_args["ORDER_BY_DESC"]) + if column is not None: + results = results.order_by(column.desc()) + + if "LIMIT" in special_args: + results = results.limit(special_args["LIMIT"]) + + results_objs = results.all() + print(f"[{round(time.time())}] SELECT RESULTS: {results_objs}") + + return results_objs @exit_gracefully def simple_insert_one(self, entity_type, **kwargs): diff --git a/FlaskWebProject/FlaskWebProject/lewy_routes.py b/FlaskWebProject/FlaskWebProject/lewy_routes.py index eb13468..f10eb3f 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_routes.py +++ b/FlaskWebProject/FlaskWebProject/lewy_routes.py @@ -1,8 +1,13 @@ from flask import render_template, request, make_response +import lewy_api_v1 +import lewy_db import lewy_globals def index(): dark_mode = request.cookies.get('darkMode', 'disabled') + # Przykładowe użycie endpointu last_goal_for(): + # roberts_last_goals_club = lewy_api_v1.last_goal_for() + # print(roberts_last_goals_club.id_klubu) stats = { 'goals': 38, 'assists': 12,