0

I am learning Google App Engine and created a simple app that queries a table on BigQuery and returns an HTML table.

Relevant pieces:

@app.route("/")
def main():

    query_job = bigquery_client.query(
        """
        SELECT DISTINCT *

        FROM github_project.labeled_data_dev
        WHERE cluster = 1
        ORDER BY commits DESC
        LIMIT 10
    """
    )

    return flask.redirect(
        flask.url_for(
            "results",
            project_id=query_job.project,
            job_id=query_job.job_id,
            location=query_job.location,
        )
    )


@app.route("/results")
def results():
    project_id = flask.request.args.get("project_id")
    job_id = flask.request.args.get("job_id")
    location = flask.request.args.get("location")

    query_job = bigquery_client.get_job(
        job_id,
        project=project_id,
        location=location,
    )

    try:
        # Set a timeout because queries could take longer than one minute.
        results = query_job.result(timeout=30)
    except concurrent.futures.TimeoutError:
        return flask.render_template("timeout.html", job_id=query_job.job_id)

    return flask.render_template("query_result.html", results=results)

I have a few variations on the above query that I would like to also return (changing the WHERE, etc).

Editing in some more information, per request.

The above script runs the query and returns a simple table. What I am after is a modification that will return multiple tables.

I have tried to edit the main script, as follows:

@app.route("/")
def main():

    query_job_1 = bigquery_client.query(
        """
        SELECT DISTINCT *

        FROM github_project.labeled_data_dev
        WHERE cluster = 1
        ORDER BY commits DESC
        LIMIT 10
    """
    )

    query1 = flask.redirect(
        flask.url_for(
            "results",
            project_id=query_job.project,
            job_id=query_job.job_id,
            location=query_job.location,
        )
    )

    query_job_2 = bigquery_client.query(
        """
        SELECT DISTINCT *

        FROM github_project.labeled_data_dev
        WHERE cluster = 2
        ORDER BY commits DESC
        LIMIT 10
    """
    )

    query2 = flask.redirect(
        flask.url_for(
            "results",
            project_id=query_job.project,
            job_id=query_job.job_id,
            location=query_job.location,
        )
    )

    return query1, query2

The idea was to then be able to call both query1 and query2 in the @app.route("/results") section and return results1, results2 which could then be used in my html template, but this doesn't work.

I believe I could potentially use a class, like the one created in the second answer here using sqlite3, but I am unsure how to rewrite it with my BigQuery connections in mind.

Any help would be greatly appreciated.

datahappy
  • 826
  • 2
  • 11
  • 29
  • 2
    It is unclear what your specific question is. Please try to elaborate or show code that you have tried. – rtenha Aug 28 '19 at 18:48
  • Will do. Thanks. – datahappy Aug 28 '19 at 18:57
  • I will preface that I don't know flask, but it looks like you are defining 2 redirects under the same route...that doesn't seem like it should work as you intend. Can you do 1 redirect with 6 parameters? `pid1,jid1,loc1,pid2,lid2,loc2` . Then in your `results` route you can run both jobs and get the data there. – rtenha Aug 28 '19 at 23:46

1 Answers1

0

Objects returned by a function cannot be "called" per se. A function call can be done, and doing so will return the objects defined in the return line. When calling the "main" function in your specific case, what is returned is a tuple with 2 elements (query1, query2). If you need to access each elements to be used in your HTML template afterward, you will want to unpack that tuple.

Take a look at this question [1] and its answers to understand the concept.
[1] How can I return two values from a function in Python?

PYB
  • 503
  • 6
  • 20