#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, но это, вероятно, интересным образом нарушит другие ваши запросы.