Reputation: 144
I am building a stock tracking application and need to automatically update the Stock model every minute with the current price (pulled from Google Finance). I need to know how to do it in a more efficient way, as there are several thousand records and my current method is very slow and inefficient.
#models.py
class Stock(models.Model):
ticker = models.CharField(max_length=200)
current_price = models.DecimalField(max_digits=20, decimal_places=5)
The below script is run through a crontab every minute
#script set to run on a crontab
from takestock.stock_getter import get_quotes
from takestock.models import Stock
class Command(BaseCommand):
help = 'Gathers current stock prices from Google Finance using stock_getter script (imported) and updates all stocks in the database to reflect the current stock price.'
def get_stock_dict(self):
all_stocks = Stock.objects.all()
stock_names = []
for single_stock in all_stocks:
stock_names.append(str(single_stock.ticker))
stock_values = get_quotes(stock_names) #a list of values which corresponds to the list of names
stock_dict = dict(zip(stock_names, stock_values)) #stock tickers and stock values zipped into dict (see below)
return stock_dict
#stock_dict looks like: {'GOOG': '73.84', 'AAPL': '520.34'}
def handle(self, *args, **options):
stock_dict = self.get_stock_dict()
for ticker, value in stock_dict.items():
stock_obj = Stock.objects.get(ticker=ticker)
stock_obj.current_price = value
stock_obj.save()
This method works, but very slowly and I imagine it is very database intensive. Is there a better way I can accomplish this? Thanks.
Upvotes: 0
Views: 498
Reputation: 174692
Use update
instead of your get/save routine:
Stock.objects.filter(ticker=ticker).update(current_price=value)
Don't fetch all the tickers every time, especially if your tickers don't change. Fetch them once, cache them in a fast k/v store; but if you must fetch them use only
to fetch only the ticker symbol and not the price as well.
Chances are, the slowest part is the fetching from Google. Since you haven't published that code, its difficult to offer any other tips.
Upvotes: 3