检查循环中数据库中是否存在记录的有效方法?
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)
我正在遍历如下所示的字典列表:
{"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)