检查循环中数据库中是否存在记录的有效方法?

Efficient way of checking if record exists in database within a loop?

我正在遍历如下所示的字典列表:

{"code:" "ST", "date": "2021-06-30", "open": 500, "close": 510, "volume": 2000}

我的数据库中有一个 table,其中 code 是另一个 table 的外键:

class HistoricStockData(models.Model):
    stock = models.ForeignKey(Stock, on_delete=models.DO_NOTHING)
    date = models.DateField()
    open_value = models.DecimalField(max_digits=8, decimal_places=3)
    close_value = models.DecimalField(max_digits=8, decimal_places=3)
    volume = models.IntegerField()

    class Meta:
        db_table = "historic_stockdata"
        verbose_name_plural = "Historic Stock Data"

然后我尝试将这些 HistoricStockData 实例插入数据库

stocks = []
for value in data: # data is the big json file that I'm parsing
    stock_name = value["code"]
    date = value["date"]
    open_price = value["open"]
    close_price = value["close"]
    volume = value["volume"]

    
    stock_info = {
        "stock": Stock.objects.get(stock=stock_name), # only append if I get a match here 
        "date": date,
        "open_value": open_price,
        "close_value": close_price,
        "volume": volume
    }
    stocks.append(stock_info)

我的问题是,如果我在

上匹配,我如何才能将每个人 stock_info 附加到 stocks
Stock.objects.get(stock=stock_name)

如果列表很大,使用 Stock.DoesNotExist 子句执行 try/catch 块似乎效率很低 - 导致大量数据库查询

这是最好的方法吗?

try: 
    stock_info = {
        "stock": Stock.objects.get(stock=stock_name),
        "date": date,
        "open_value": open_price,
        "close_value": close_price,
        "volume": volume
    }
except Stock.DoesNotExist:
    continue

这就是您当前的实施方式。

s = Stock.objects.get(stock=stock_name, None)
stocks = []
if s:
   stock_info = {
        "stock": s
        "date": date,
        "open_value": open_price,
        "close_value": close_price,
        "volume": volume
    }
    stocks.append(stock_info)

出于性能原因,做更像这样的事情可能是有利的(确切的语法可能不正确:

stock_names = (_['code'] for _ in data)
s = Stock.objects.in_bulk(stock_name=stock_names)
stocks = []
for d in data:
  if d['code'] in s:
    stocks.append(...)

您可以进行一次查询以获取所有需要的 Stock 实例并将它们放入字典中。有了这个,您就可以非常轻松地进行查找以检查是否存在股票:

stock_names = [value['code'] for value in data]
stock_map = {stock.stock: stock for stock in Stock.objects.filter(stock__in=stock_names)}

stocks = []
for value in data:
    stock_name = value["code"]
    date = value["date"]
    open_price = value["open"]
    close_price = value["close"]
    volume = value["volume"]

    stock = stock_map.get(stock_name)
    if stock is not None:
        stock_info = {
            "stock": stock
            "date": date,
            "open_value": open_price,
            "close_value": close_price,
            "volume": volume
        }
        stocks.append(stock_info)