简体   繁体   中英

Joining and iterating through foreign-key tables with Django

I have the following 2 Django models:

from django.db import models

class Stock(models.Model):
    symbol = models.CharField(db_index=True, max_length=5, null=False, editable=False, unique=True)

class PriceHistory(models.Model):
    stock = models.ForeignKey(Stock, related_name='StockHistory_stock', editable=False)
    trading_date = models.DateField(db_index=True, null=False, editable=False)
    price = models.DecimalField(max_digits=12, db_index=True, decimal_places=5, null=False, editable=False)
    class Meta:
        unique_together = ('stock', 'date')

Obviously this leads to two DB tables being created: myapp_stock and myapp_pricehistory . These tables have 2 and 4 columns respectively. The first table contains thousands of rows. The second table contains millions of rows.

I want to join the tables, sort the resultant rows and iterate through these rows one-by-one print them. This is how I plan to do it:

for i in PriceHistory.object.all().order_by('stock__symbol', 'trading_date'):
    print '{} {}: {}'.format(i.stock.symbol, i.trading_date, i.price)

Is this the most efficient way to do it to minimize calls to the database? I want it to run only one SQL query. I'm concerned that the above code will run a separate query of the myapp_stock table each time it goes through the for loop. Is this concern valid? If so, how to avoid that?

Basically, I know the ideal SQL would look something like this. How can I get Django to execute something similar?:

select
   s.symbol,
   ph.trading_date,
   ph.price
from
    myapp_stock as s,
    myapp_pricehistory as ph
where
    ph.stock_id=s.id
order by
    s.symbol asc, 
    ph.trading_date asc

You need to use select_related to avoid making an additional query for each item in the loop:

histories = PriceHistory.objects.all().select_related('stock')\
                        .order_by('stock__symbol', 'trading_date')

for i in histories:
    print '{} {}: {}'.format(i.stock.symbol, i.trading_date, i.price)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM