【问题标题】:Intermittent KeyError with Dash-Plotly Python app deployed to Heroku将 Dash-Plotly Python 应用程序部署到 Heroku 的间歇性 KeyError
【发布时间】:2021-12-04 00:20:43
【问题描述】:

我已经使用 Heroku 的“heroku git CLI”选项将 Dash-Plotly Python 应用程序部署到 Heroku。我按照 Heroku 的指示进行了部署,部署本身很顺利。事实上,该应用程序在 75% 的时间里都能正常工作。 (另请注意,该应用在本地运行时可以完美运行。)

应用程序本身旨在搜索产品数据库并显示有关所选产品的性能特征。用户将搜索标准输入网络表单并通过按下“搜索”按钮启动搜索。所有产品数据都存储在应用程序本地的“数据”文件夹(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'

'freq-low' 是用户在按下“搜索”按钮之前输入的值。我知道该值存在,因为它在按搜索之前手动输入了网页。

请注意,上面的日志是“freq-low”变量导致 KeyError 的示例,但其他变量也会发生错误。它不仅限于围绕“freq-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 输入表单期间由破折号创建的。在创建对象期间,该类确实从本地 Excel (.xlsx) 文件中提取数据。此文件中的标题之一是“freq-low”,它被转换为 Excel 输入的每一行的键值对。 excel 表的行代表不同的产品,它们的属性作为字典读入类。因此,“class_name.products.values()”是一个字典列表。我依靠在“search_products”函数调用之前正确及时地读取本地excel数据来完成。正在读入的数据量非常小,约为 12KB。

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

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

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

【问题讨论】:

  • 请显示发生错误的代码。你是否依赖于记忆中的任何东西?你在使用全局变量吗?
  • 嗨@Chris。谢谢参观。我用显示错误发生位置的代码更新了帖子。我认为您可能会对记忆问题有所了解。我确实依赖于在函数调用运行之前从 excel 文件中读取数据来完成,但我没有任何东西可以在调用之前验证读取是否成功。

标签: python heroku plotly-dash keyerror intermittent


【解决方案1】:

你有没有尝试过以下一些变体

from dash.exceptions import PreventUpdate

...

 def search_products(class_name, inputs):
     if not class_name and not inputs:
        raise PreventUpdate

那么剩下的代码呢?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 2021-04-15
    • 2012-07-16
    • 2018-11-23
    相关资源
    最近更新 更多