One of the most powerful features in PushMetrics is the ability to reference data from one task in another. This creates dependencies between tasks and allows you to build workflows where each step builds on the results of previous steps.


How Task References Work

Every executable task in a notebook produces output data. You can reference this output in any downstream task using Jinja syntax with the task's name:

{{ task_name.data }}

When a task references another, PushMetrics automatically creates a dependency. During execution, the referenced task will always run first, ensuring the data is available when needed.


Referencing SQL Query Results

SQL query blocks are the most commonly referenced tasks. Their output is an array of row objects.

Access a Single Value

To get a specific column value from the first row:

{{ query_1.data[0].column_name }}

For example, if query_1 returns:

name revenue region
Acme 50000 East
Beta 30000 West

Then:

  • {{ query_1.data[0].name }} returns Acme
  • {{ query_1.data[0].revenue }} returns 50000
  • {{ query_1.data[1].region }} returns West

Access Row Count

{{ query_1.data | length }}

Iterate Over Rows

In a Jinja loop (useful in emails, Slack messages, or SQL):

{% for row in query_1.data %}
  {{ row.name }}: ${{ row.revenue }}
{% endfor %}

Use in Another SQL Query

Reference a query result as a subquery or value in another SQL block:

SELECT *
FROM orders
WHERE region = '{{ query_1.data[0].region }}'

Or reference the entire SQL statement as a subquery:

SELECT *
FROM ({{ query_1 }}) AS subquery
WHERE revenue > 10000

When referencing just {{ query_1 }} (without .data), the raw SQL text of that block is inserted, allowing you to compose modular queries.


Referencing Other Task Types

API Call Results

{{ api_1.data }}           -- Full response body
{{ api_1.data.field }}     -- Specific field from JSON response

OpenAI Prompt Response

{{ openAI_1.data.choices[0].message.content }}   -- Response text
{{ openAI_1.data }}                               -- Full API response

Parameter Values

{{ param_1.value }}        -- The current value of a parameter block

Tableau Export

Tableau exports produce file attachments rather than data. Use .export() to attach them to delivery tasks.


Using .export() for Attachments

To pass files (charts, CSV exports, Tableau exports, DOCX documents) to delivery tasks like Email, Slack, Google Drive, or SFTP, use the .export() function:

{{ query_1.export() }}     -- CSV export of query results
{{ chart_1.export() }}     -- Chart image
{{ tableau_1.export() }}   -- Tableau export file
{{ docx_1.export() }}      -- Generated DOCX document

The .export() reference is used in the Attachments section of Email and Slack blocks, or as the Source input for file upload blocks (Google Drive, GCP Cloud Storage, SFTP).


Previewing Parsed Results

To verify that your references resolve correctly before executing:

  1. Click the {{ button on the left side of a SQL block to preview the Jinja-parsed query with all references expanded.
  2. In the execution output, click the </> button to inspect the full response data of any task.

This helps you debug reference paths and confirm the data structure.


Task Execution Order

PushMetrics automatically determines the execution order based on references:

  • If Task B references {{ task_a.data }}, then Task A will always execute before Task B.
  • Tasks with no dependencies between them may execute in parallel.
  • Circular references (Task A references Task B, and Task B references Task A) are not allowed and will produce an error.

You can visualize the dependency graph of your notebook using the DAG view.


Common Patterns

Conditional Logic Based on Query Results

Use an IF/ELSE block with a task reference as the condition:

{{ query_1.data[0].revenue > 100000 }}

Dynamic Email Recipients from a Query

In an Email block's To field:

{{ query_1.data[0].email }}

Building Summary Messages

In a Slack or Email message body:

This week's revenue: ${{ query_1.data[0].total_revenue }}
Active users: {{ query_2.data[0].user_count }}
Top region: {{ query_1.data[0].top_region }}

Chaining Multiple Queries

Query 1 fetches a list, Query 2 uses a value from Query 1:

-- query_2
SELECT * FROM detailed_metrics
WHERE client_id = '{{ query_1.data[0].client_id }}'