在两条烧瓶路线之间传递熊猫数据框和其他对象

时间:2018-12-07 18:53:28

标签: python flask

我有一个flask Webapp,我正尝试使用它来查看/检索数据库中的某些数据(elasticsearch)。出于统计原因,数据是简单的随机样本。来自数据库查询的数据将作为pandas数据帧返回,并在一条路径中创建。我需要将此数据帧传递到第二条路由。

由于随机性,如果我尝试在第二条路线中重新运行数据库查询,它将自然返回一个不同的随机样本。出于超出此问题范围的原因,elasticsearch确实支持传递种子,但是这些大大降低了数据库查询的速度(原则上,我认为这不需要两个独立的数据库查询)。

我有一条view_data路由,可以让用户查看数据,还有第二条download_data路由,可以让用户将文件下载为CSV,TSV或JSON。我想让用户查看数据,如果数据是预期的,请单击URL下载他们正在查看的数据集。

view_data看起来像这样:

@app.route('/view_data', methods=['GET'])
def view_data():
  df = get_random_sample_from_database()
  return render_template('view_data.html', dataframe = df)

用于查看数据view_data.html的html:

<html>
  <body>
    <!-- this shows data to user -->
    <pre>
      {% if not dataframe.empty %}
      {{dataframe.__repr__()|safe}}
      {% endif %}
    </pre>

    <!-- when user clicks this URL, it will download data rendered above, not sure how to pass in above dataframe -->
    <a href="{{ url_for('download_data'}}">download above data</a>
  <body>
</html>

download_data的功能:

@app.route('/download_data', methods=['GET'])
def download_data():
  # Use some magic here to get the df created in view_data
  return Response(
    df.to_csv(),
    mimetype="text/csv",
    headers={"Content-disposition":"attachment; filename=data.csv"})

以下是我研究过的几种方法:

  1. 烧瓶会话:这似乎将数据作为安全cookie存储在用户的浏览器中。我不想走这条路,因为随机样本的范围可能是1MB到100 + MB。
  2. flask.g:我已经尝试过此操作,但是由于不断收到'_AppCtxGlobals' object has no attribute类型错误,因此无法弄清楚该如何正确地进行操作。

这是我尝试的(2):

from flask import g

@app.route('/view_data', methods=['GET'])
def view_data():
  df = get_random_sample_from_database()
  g.data = df
  return render_template('view_data.html', dataframe = df)

@app.route('/download_data', methods=['GET'])
def download_data():
  df = g.data
  return Response(
    df.to_csv(),
    mimetype="text/csv",
    headers={"Content-disposition":"attachment; filename=data.csv"})

是否有一种简单的方法可以在view_data中生成数据帧并将其传递给download_data?是否有更好的方法让用户查看数据并选择下载数据?

0 个答案:

没有答案