Как проверить, существует ли ключ уже в базе данных с помощью Firebase и Python?

# #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 деталь, похоже, не возвращает ошибку.