From 7dce92f5c1647138c7ec841a534840070e6c5deb Mon Sep 17 00:00:00 2001 From: Greg Date: Sat, 17 May 2025 02:10:49 +0200 Subject: [PATCH] Database transaction code adapted for more safety --- app.py | 78 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/app.py b/app.py index 9241741..d1dde68 100644 --- a/app.py +++ b/app.py @@ -76,42 +76,54 @@ def db_to_json(): def json_to_db(data): try: - db.session.query(Attendance).delete() - db.session.commit() - db.session.query(GuestName).delete() - db.session.commit() - db.session.query(Date).delete() - db.session.commit() - db.session.query(Player).delete() - db.session.commit() + # Start a single transaction for all operations + with db.session.begin(): + # Clear existing attendance records + db.session.query(Attendance).delete() + db.session.query(GuestName).delete() + + # Update players - keep existing ones, add new ones + existing_players = {p.name: p for p in Player.query.all()} + for name in data.get("players", []): + if name not in existing_players: + db.session.add(Player(name=name)) + + # Update dates - keep existing ones, add new ones + existing_dates = {d.date_str: d for d in Date.query.all()} + for date_str in data.get("dates", []): + if date_str not in existing_dates: + date = Date(date_str=date_str) + db.session.add(date) + existing_dates[date_str] = date + + # Refresh player list after potential additions + player_dict = {p.name: p for p in Player.query.all()} + + # Add attendance records + for date_str in data.get("dates", []): + date = existing_dates[date_str] + for idx, player_name in enumerate(data["players"] + [data["guest"]]): + key = f"{date_str}|{idx}" + status = data["attendance"].get(key) + if status and player_name in player_dict: + player = player_dict[player_name] + # Convert boolean True to string 'yes' + status_value = 'yes' if status is True else status + # Only add if status is one of the valid values + if status_value in ['yes', 'no', 'maybe']: + db.session.add(Attendance(date_id=date.id, player_id=player.id, status=status_value)) + + # Add guest name if present + guest_name = data.get("guestNames", {}).get(date_str) + if guest_name: + db.session.add(GuestName(date_id=date.id, name=guest_name)) + + # The transaction will be committed automatically if no exceptions occur except Exception as e: - db.session.rollback() - print("Error during deletion:", e) + # The transaction will be rolled back automatically if an exception occurs + print("Error during database operation:", e) raise - # Insert players from JSON - for name in data.get("players", []): - db.session.add(Player(name=name)) - db.session.commit() - - # Insert dates and attendance - for date_str in data.get("dates", []): - date = Date(date_str=date_str) - db.session.add(date) - db.session.commit() - for idx, player_name in enumerate(data["players"] + [data["guest"]]): - key = f"{date_str}|{idx}" - status = data["attendance"].get(key) - if status: - player = Player.query.filter_by(name=player_name).first() - if player: - # Save status as 'yes', 'no', or 'maybe' - db.session.add(Attendance(date_id=date.id, player_id=player.id, status='yes' if status is True else status if status in ['no', 'maybe'] else None)) - guest_name = data.get("guestNames", {}).get(date_str) - if guest_name: - db.session.add(GuestName(date_id=date.id, name=guest_name)) - db.session.commit() - @app.route('/')