# #python #firebase #firebase-realtime-database #optimization
Вопрос:
По сути, я буду использовать базу данных этой структуры:
чтобы отслеживать опыт пользователей. В этом xp_data
разделе будет несколько временных меток и номеров xp для каждой временной метки. Каждые 24 часа будет запускаться функция, которая будет регистрировать опыт пользователей. Я хочу иметь какой-то способ проверить, есть ли игрок уже в базе данных (и если да, добавьте к их существующему количеству xp), а если нет, создайте для них новый узел. Вот мой код для записи на сервер:
db_ref = db.reference('/')
for i in range(100):
tom = await mee6API.levels.get_leaderboard_page(i)
if xp_trigger:
break
this_lb_list = {}
for l in tom['players']:
if l['xp'] < 300:
xp_trigger = True
break
this_lb_list.update({l['id']: {'name': l['username'], 'xp_data': {time.strftime(time_format_str, time.gmtime()): l['xp']}}})
details = [{ int(l['id']) : l['xp']}]
print(i)
db_ref.update(this_lb_list)
По сути, этот код просматривает каждую страницу в таблице лидеров, получает XP для каждого пользователя и добавляет его в диктант, который затем используется для обновления базы данных. с этим кодом есть две проблемы, одна из которых заключается в том, что он не проверяет, существует ли пользователь уже, что означает, и это вторая проблема, что он перезаписывает существующие данные пользователя. Я также попытался записать данные для каждого игрока индивидуально, но проблема 1 все еще оставалась проблемой, и это было мучительно медленно. Что я могу сделать, чтобы исправить это?
Комментарии:
1. Как пользователь идентифицируется в вашей базе данных и в вашем коде?
2. @FrankvanPuffelen Они идентифицируются на основе их идентификатора, который является номером верхнего уровня, который вы видите в базе данных.
3. Спасибо, думаю, теперь я понял, в чем проблема. Позвольте мне написать для вас краткий ответ.
Ответ №1:
Когда вы передаете значение для свойства update()
, это значение заменяет все существующее значение свойства в базе данных. Таким образом, хотя update()
свойства, которые вы не указали в вызове, остаются неизменными, это полностью заменяет любое указанное вами свойство.
Чтобы добавить значение к существующему свойству, вам потребуется указать весь путь в качестве ключа, разделив различные дочерние узлы /
.
Так что что-то вроде:
this_lb_list.update({'xp_data/13-Auth-2021': l['xp']})
При этом будет записываться только 13-Auth-2021
оф xp_data
, оставляя все остальные дочерние узлы xp_data
неизмененными.
Вы, конечно, захотите использовать переменную для даты/времени, но важно то, что вы указываете ее в ключе, а не в значении словаря.
Комментарии:
1. Это решение действительно работает, когда пользователь находится в базе данных, но мне все еще нужен какой-то способ определить, существует ли пользователь еще. Вы в курсе? есть ли способ сделать это?
2. Чтобы узнать, есть ли данные для пользователя, вам нужно прочитать эти данные.
3. Это должно сработать, да?
try: tp_ref = db.reference(str(l['id'])) x = tp_ref.get() lb_list_existing.update( { f"{l['id']}/xp_data/{time.strftime(time_format_str, time.gmtime())}" : l['xp'] }) except Exception as e: print(e) this_lb_list.update({l['id']: {'name': l['username'], 'xp_data' : {time.strftime(time_format_str, time.gmtime()): l['xp']}}})
Однако, несмотря на то, что пользователь не существует,try
деталь, похоже, не возвращает ошибку.