Задания на Сельдерее сохраняют данные неправильно или слишком

#python #celery

#python #сельдерей

Вопрос:

у меня есть задание celery для извлечения некоторых криптографических данных из coinmarketcap.com. Если задание запускалось несколько раз, у меня в базе данных нет 100 результатов, я всегда получаю 101-108 записей. Почему это?

tasks.py

 def get_exchange_rate():
    api_url = "https://api.coinmarketcap.com/v1/ticker/?limit=100"
    try:
        exchange_rates = requests.get(api_url).json()
        for exchange_rate in exchange_rates:
            CryptoPrices.objects.update_or_create(
                key=exchange_rate['id'],
                symbol=exchange_rate['symbol'],
                defaults={
                    "market_cap_usd": round(float(exchange_rate['market_cap_usd']), 3),
                    "volume_usd_24h": round(float(exchange_rate['24h_volume_usd']), 3),
                    "value": round(float(exchange_rate['price_usd']), 2)
                })
        logger.info("Crypto rate(s) updated successfully.")
    except Exception as e:
        print(e)
  

есть ли какой-либо способ ограничить максимальное количество записей в базе данных для этой таблицы?
В итоге я хочу иметь ровно 100

с уважением

Ответ №1:

Вы полагаетесь на согласованность порядка в ленте coinmarket cap. Поскольку он ранжируется по marketcap, монеты будут выпадать в нижней части списка, а поскольку вы используете update_or_create(), новые записи будут созданы, а старые останутся висящими.

Если вы хотите самостоятельно отслеживать топ-100, я бы посоветовал вам получить топ-150 и выполнить собственную фильтрацию по порядку. В качестве альтернативы добавьте время обновления к вашей модели (auto_now = True) и после обновления удалите все, что превышает определенный возраст.

Комментарии:

1. Разве я не могу просто перезаписать старые и взять только 100 из моего запроса по URL api — ?limit = 100?

2. @venom у вас есть 2 варианта, если вам абсолютно необходимо только 100 строк в таблице (оба являются неоптимальными). Удалите все перед запуском или отследите, какие из них обновлены, и удалите остальные после обновления. Ужасным способом было бы использовать ранжирование в качестве PK, но это, вероятно, интересным образом нарушит другие ваши запросы.