batch update/create for db score updates
This commit is contained in:
@@ -75,11 +75,56 @@ def _save_db_scores(wordle_day: wordlinator.utils.WordleDay, scores: dict):
|
||||
if not hole_data:
|
||||
return
|
||||
game_no = hole_data.game_no
|
||||
|
||||
db_users = db.get_users()
|
||||
db_holes = db.get_holes(game_no)
|
||||
db_scores = db.get_scores(game_no)
|
||||
|
||||
to_update = []
|
||||
to_create = []
|
||||
|
||||
for user, score_list in scores.items():
|
||||
if not db.get_user(user):
|
||||
db_user_match = [u for u in db_users if u.username == user]
|
||||
db_user = db_user_match[0] if db_user_match else None
|
||||
|
||||
if not db_user:
|
||||
continue
|
||||
|
||||
for day, score_entry in enumerate(score_list, start=1):
|
||||
db.add_score(user, game_no, day, score_entry)
|
||||
try:
|
||||
score_entry = int(score_entry)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
score_match = [
|
||||
s
|
||||
for s in db_scores
|
||||
if s.user_id.username == user and s.hole_id.hole == day
|
||||
]
|
||||
db_score = score_match[0] if score_match else None
|
||||
|
||||
if db_score:
|
||||
if db_score.score != score_entry:
|
||||
db_score.score = score_entry
|
||||
to_update.append(db_score)
|
||||
|
||||
else:
|
||||
hole = [h for h in db_holes if h.hole == day][0]
|
||||
to_create.append(
|
||||
{
|
||||
"score": score_entry,
|
||||
"user_id": db_user.user_id,
|
||||
"game_id": hole.game_id.game_id,
|
||||
"hole_id": hole.hole_id,
|
||||
}
|
||||
)
|
||||
|
||||
if to_update:
|
||||
db.bulk_update_scores(to_update)
|
||||
|
||||
if to_create:
|
||||
db.bulk_insert_scores(to_create)
|
||||
return
|
||||
|
||||
|
||||
async def main_update(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import typing
|
||||
|
||||
import peewee
|
||||
|
||||
@@ -54,6 +55,9 @@ class WordleDb:
|
||||
except peewee.DoesNotExist:
|
||||
return None
|
||||
|
||||
def get_users(self):
|
||||
return list(User.select())
|
||||
|
||||
def get_user_id(self, username):
|
||||
user = self.get_user(username)
|
||||
return user.twitter_id if user else None
|
||||
@@ -75,6 +79,10 @@ class WordleDb:
|
||||
except peewee.DoesNotExist:
|
||||
return Hole.create(hole=hole_no, game_id=round.game_id)
|
||||
|
||||
def get_holes(self, round_no):
|
||||
round = self.get_or_create_round(round_no)
|
||||
return Hole.select().filter(game_id=round.game_id)
|
||||
|
||||
def create_round_holes(self, round_no):
|
||||
for hole_no in range(1, 19):
|
||||
self.get_or_create_hole(round_no, hole_no)
|
||||
@@ -108,3 +116,12 @@ class WordleDb:
|
||||
def get_scores(self, round_no):
|
||||
round = self.get_or_create_round(round_no)
|
||||
return Score.select().filter(Score.game_id == round.game_id)
|
||||
|
||||
def bulk_insert_scores(self, scores: typing.List[typing.Dict]):
|
||||
with db.atomic():
|
||||
for batch in peewee.chunked(scores, 50):
|
||||
Score.insert_many(batch).execute()
|
||||
|
||||
def bulk_update_scores(self, scores: typing.List[Score]):
|
||||
with db.atomic():
|
||||
Score.bulk_update(scores, fields=[Score.score], batch_size=50)
|
||||
|
||||
Reference in New Issue
Block a user