使用Dash-Plotly Python应用部署到Heroku时出现间歇性KeyError



我已经使用Heroku的" Heroku git cli "部署了一个Dash-Plotly Python应用程序到Heroku选择。我遵照了Heroku的指示,部署过程也很顺利。事实上,该应用程序的正常运行率为75%。(还需要注意的是,应用程序在本地运行时可以完美运行。)

该应用程序本身旨在搜索产品数据库并显示所选产品的性能特征。用户将搜索条件输入到web表单中,然后使用"search"开始搜索。按钮按下。所有产品数据都存储在本地应用程序的"data"中。文件夹(excel文件).

我遇到的问题是应用程序"看起来";在Heroku上没有响应,需要多次点击按钮或复选框来触发所需的操作。

当我打开日志时,我看到按下按钮后的输出如下:

2021-10-15T19:25:17.768450+00:00 app[web.1]: Exception on /_dash-update-component [POST]
2021-10-15T19:25:17.768474+00:00 app[web.1]: Traceback (most recent call last):
2021-10-15T19:25:17.768475+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
2021-10-15T19:25:17.768475+00:00 app[web.1]: response = self.full_dispatch_request()
2021-10-15T19:25:17.768476+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
2021-10-15T19:25:17.768476+00:00 app[web.1]: rv = self.handle_user_exception(e)
2021-10-15T19:25:17.768476+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
2021-10-15T19:25:17.768477+00:00 app[web.1]: rv = self.dispatch_request()
2021-10-15T19:25:17.768477+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
2021-10-15T19:25:17.768477+00:00 app[web.1]: return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
2021-10-15T19:25:17.768478+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/dash/dash.py", line 1096, in dispatch
2021-10-15T19:25:17.768478+00:00 app[web.1]: response.set_data(func(*args, outputs_list=outputs_list))
2021-10-15T19:25:17.768478+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.9/site-packages/dash/dash.py", line 1017, in add_context
2021-10-15T19:25:17.768479+00:00 app[web.1]: output_value = func(*args, **kwargs)  # %% callback invoked %%
2021-10-15T19:25:17.768479+00:00 app[web.1]: File "/app/productsearch.py", line 1329, in table_interact
2021-10-15T19:25:17.768480+00:00 app[web.1]: products = search_products(classname, inputs)
2021-10-15T19:25:17.768480+00:00 app[web.1]: File "/app/productsearch.py", line 943, in search_products
2021-10-15T19:25:17.768480+00:00 app[web.1]: elif (low == None or (product['freq-low'] <= low and high <= product['freq-high'])):
2021-10-15T19:25:17.768481+00:00 app[web.1]: KeyError: 'freq-low'

' frequency -low'是用户在"搜索"前输入的值。按钮按下。我知道这个值在那里,因为它是在按搜索之前手动输入到网页的。

请注意,上面的日志是' frequency -low'变量导致KeyError的示例,但错误也会发生在其他变量上。它不仅仅局限于' frequency -low'变量周围的代码。

编辑如下,显示发生异常的代码中的函数:

def search_products(class_name, inputs):
'''
This function is used to create a list of products that meet the search
criteria (product type "class_name" and user "inputs").

Parameters:
inputs: list of Float64 values
input list of Float64 values from user inputs
class_name: string 
input string referencing the product class type (i.e "B" for Balun)
Returns:
lists of dicts
list of dicts with product data from the productspec.xls sheet           
'''
if class_name == M:
low_rf, high_rf, low_lo, high_lo, low_if, high_if, low_lodr, high_lodr = inputs
else:
low, high = inputs
data = []
for product in class_name.products.values():
if class_name == M:
if (
(low_rf == None or (product['rf-low'] <= low_rf and high_rf <= product['rf-high']))
and (low_lo == None or (product['lo-low'] <= low_lo and high_lo <= product['lo-high']))
and (low_if == None or (product['if-low'] <= low_if and high_if <= product['if-high']))
and (low_lodr == None or (product['lodr-low'] <= low_lodr and high_lodr <= product['lodr-high']))
):
data.append(product)
elif (low == None or (product['freq-low'] <= low and high <= product['freq-high'])):
data.append(product)
return data

对象"class_name";是在生成HTML输入表单期间由破折号创建的。在创建对象期间,类DOES从本地Excel (.xlsx)文件中拉入数据。这个文件中的一个头是" frequency -low"将其转换为Excel输入的每行的键值对。excel工作表的行表示不同的产品,这些产品的属性作为字典读入类。所以,"class_name.products.values()";是一个字典列表。在"搜索产品"之前,我依靠正确及时地读取本地excel数据来完成搜索。函数调用。读取的数据量非常小,约为12KB。

需要注意的另一件重要的事情是,这种行为不是确定的。它不是可重复的,因为它总是在第一次或第二次尝试时失败。有时它可以立即工作,有时需要3-4次点击。但到目前为止,只要点击足够多,它总是有效的。

我会提到故障排除,但到目前为止我不知道该怎么做,因为我没有得到任何单一变量或函数故障的指示。

UPDATE:我有几个持久的全局变量,用于限制对数据源的调用。在删除所有这些并验证代码仍然在本地执行之后……在Heroku上仍然存在间歇性键错误的问题。(

您是否尝试过使用以下的一些变体

from dash.exceptions import PreventUpdate
...
def search_products(class_name, inputs):
if not class_name and not inputs:
raise PreventUpdate

那么剩下的代码呢?