> ## Documentation Index
> Fetch the complete documentation index at: https://docs.morf.health/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Save To Bigquery

> Documentation for the Save To Bigquery action for Google

![images/google.svg](https://mintcdn.com/morfhealth/EU2WCxuXGIUQcziR/images/google.svg?fit=max\&auto=format\&n=EU2WCxuXGIUQcziR\&q=85\&s=3baaab9ce0dfd622797f2a1acd4c5309)

## Getting Started

Automate your healthcare workflows with Google BigQuery integrations and Morf. BigQuery is a cloud-based data warehouse for analyzing and querying large datasets. Save event data from a Morf workflow to a BigQuery table.

## Grant Morf access to BigQuery

1. Create a new dataset. This recommended approach to dataset management ensures Morf only has access to the necessary tables. Follow Google's instructions on [creating a new dataset](https://cloud.google.com/bigquery/docs/datasets).
2. Share your dataset with Morf. Follow Google's instructions on [granting access to a dataset](https://cloud.google.com/bigquery/docs/control-access-to-resources-iam#grant_access_to_a_dataset).
   * Role: BigQuery Data Editor (`roles/bigquery.dataEditor`)
   * Email: `primary-workload-sa@morf-prod-5f7d.iam.gserviceaccount.com`

> [!WARNING]
>
> This role should be granted at the dataset level so Morf doesn't have unneccessary access to other data.

Use Morf's [Save to BigQuery action](https://docs.morf.health/docs/actions/google/v1/save_to_bigquery.md) to store event data directly in BigQuery from a workflow.

# Parameters

**Action** `Parameters`

**parameters**

**Project ID** `string` *required*

This field maps to the destination API `projectID` field.

**Dataset ID** `string` *required*

This field maps to the destination API `datasetID` field.

**Table Name** `string`

This field maps to the destination API `tableName` field.

**Fields** `Map\<string,dynamic (any)\>`

`HI` `ID` `PII`
This field maps to the destination API `fields` field.

**Additionally Include Event Fields At The Top Level** `bool`

This field maps to the destination API `additionallyIncludeEventFieldsAtTheTopLevel` field.

```json Result Object Example theme={null}
{
  "$result_object_key": {
    "estimated_row_count": 1000,
    "partition": "2025-03-17",
    "schema_differences": [
      {
        "description": "Number of visits of this patient",
        "field": "number_of_visits",
        "field_addition": {},
        "field_type": "INTEGER",
        "field_update": {
          "new_description": "Number of visits of this patient",
          "new_field_type": "STRING",
          "new_repeated": true,
          "new_required": false
        },
        "nested_field_changes": null,
        "repeated": false,
        "required": true
      }
    ],
    "table_name": "healthie_patient_updated",
    "table_schema": [
      {
        "description": "Number of visits of this patient",
        "fields": null,
        "name": "number_of_visits",
        "repeated": false,
        "required": true,
        "type": "INTEGER"
      }
    ]
  }
}
```

```json Result Object Description theme={null}
{
  "$result_object_key": {
    "estimated_row_count": "Estimated total number of rows including the data just inserted",
    "partition": "Date partition the data was saved to",
    "schema_differences": {
      "description": "Field description",
      "field": "Field name",
      "field_addition": {},
      "field_type": "Field type",
      "field_update": {
        "new_description": "New description",
        "new_field_type": "New field type",
        "new_repeated": "New value for whether the field is a list",
        "new_required": "New value for whether the field is required"
      },
      "nested_field_changes": null,
      "repeated": "If the field is a list",
      "required": "If the field is required"
    },
    "table_name": "Table name used to save the data",
    "table_schema": {
      "description": "Field description",
      "fields": null,
      "name": "Field name",
      "repeated": "If the field is a list",
      "required": "If the field is required",
      "type": "Field type"
    }
  }
}
```

### Result Object Field Details

You can use the result of the action's data as inputs to downstream workflow actions.

Each fetch action requires an object name, which nests the action's result data inside the downstream data context in the workflow. See [Passing Data Between Actions](https://docs.morf.health/docs/knowledge_base/passing_data_between_actions.md) for how to set it and reference the result from downstream nodes.

Here we demonstrate how to refer to this data using the prefix `$result_object_key`.

**SaveToBigQueryResponse** `Fetch Action Response Object`

**fields**

**partition** `values.v1.Date` *required*

Date partition the data was saved to

```json CEL theme={null}
$result_object_key.partition
```

```json Example theme={null}
"2025-03-17"
```

**estimated\_row\_count** `uint64` *required*

Estimated total number of rows including the data just inserted

```json CEL theme={null}
$result_object_key.estimated_row_count
```

```json Example theme={null}
1000
```

**schema\_differences** `[]object` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.schema_differences
```

```json Example theme={null}
[
{
"description": "Number of visits of this patient",
"field": "number_of_visits",
"field_addition": {},
"field_type": "INTEGER",
"field_update": {
"new_description": "Number of visits of this patient",
"new_field_type": "STRING",
"new_repeated": true,
"new_required": false
},
"nested_field_changes": null,
"repeated": false,
"required": true
}
]
```

**schema\_differences.map(x, x.field)** `[]string` *required*

Mapped array of: Field name

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.field)
```

```json Example theme={null}
[
"number_of_visits"
]
```

**schema\_differences.map(x, x.description)** `[]string` *required*

Mapped array of: Field description

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.description)
```

```json Example theme={null}
[
"Number of visits of this patient"
]
```

**field\_type** `google.bigquery.v1.FieldType` *required*

Mapped array of: Field type

```json CEL theme={null}
field_type
```

```json Example theme={null}
google.bigquery.v1.FieldType.STRING
google.bigquery.v1.FieldType.BYTES
google.bigquery.v1.FieldType.INTEGER
google.bigquery.v1.FieldType.FLOAT
google.bigquery.v1.FieldType.BOOLEAN
google.bigquery.v1.FieldType.TIMESTAMP
google.bigquery.v1.FieldType.RECORD
google.bigquery.v1.FieldType.DATE
google.bigquery.v1.FieldType.TIME
google.bigquery.v1.FieldType.DATETIME
google.bigquery.v1.FieldType.NUMERIC
google.bigquery.v1.FieldType.GEOGRAPHY
google.bigquery.v1.FieldType.BIGNUMERIC
google.bigquery.v1.FieldType.INTERVAL
google.bigquery.v1.FieldType.JSON
google.bigquery.v1.FieldType.RANGE
```

**schema\_differences.map(x, x.repeated)** `[]bool` *required*

Mapped array of: If the field is a list

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.repeated)
```

```json Example theme={null}
[
false
]
```

**schema\_differences.map(x, x.required)** `[]bool` *required*

Mapped array of: If the field is required

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.required)
```

```json Example theme={null}
[
true
]
```

**schema\_differences.map(x, x.nested\_field\_changes)** `[]bool` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.nested_field_changes)
```

```json Example theme={null}
[
[
{
"description": "Number of visits of this patient",
"field": "number_of_visits",
"field_addition": {},
"field_type": "INTEGER",
"field_update": {
  "new_description": "Number of visits of this patient",
  "new_field_type": "STRING",
  "new_repeated": true,
  "new_required": false
},
"nested_field_changes": null,
"repeated": false,
"required": true
}
]
]
```

**schema\_differences.map(x, x.field\_addition)** `[]bool` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.field_addition)
```

```json Example theme={null}
[
{}
]
```

**schema\_differences.map(x, x.field\_update)** `[]bool` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.schema_differences.map(x, x.field_update)
```

```json Example theme={null}
[
{
"new_description": "Number of visits of this patient",
"new_field_type": "STRING",
"new_repeated": true,
"new_required": false
}
]
```

**field\_update.new\_field\_type** `google.bigquery.v1.FieldType`

New field type

```json CEL theme={null}
field_update.new_field_type
```

```json Example theme={null}
google.bigquery.v1.FieldType.STRING
google.bigquery.v1.FieldType.BYTES
google.bigquery.v1.FieldType.INTEGER
google.bigquery.v1.FieldType.FLOAT
google.bigquery.v1.FieldType.BOOLEAN
google.bigquery.v1.FieldType.TIMESTAMP
google.bigquery.v1.FieldType.RECORD
google.bigquery.v1.FieldType.DATE
google.bigquery.v1.FieldType.TIME
google.bigquery.v1.FieldType.DATETIME
google.bigquery.v1.FieldType.NUMERIC
google.bigquery.v1.FieldType.GEOGRAPHY
google.bigquery.v1.FieldType.BIGNUMERIC
google.bigquery.v1.FieldType.INTERVAL
google.bigquery.v1.FieldType.JSON
google.bigquery.v1.FieldType.RANGE
```

**table\_schema** `[]object` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.table_schema
```

```json Example theme={null}
[
{
"description": "Number of visits of this patient",
"fields": null,
"name": "number_of_visits",
"repeated": false,
"required": true,
"type": "INTEGER"
}
]
```

**table\_schema.map(x, x.name)** `[]string` *required*

Mapped array of: Field name

```json CEL theme={null}
$result_object_key.table_schema.map(x, x.name)
```

```json Example theme={null}
[
"number_of_visits"
]
```

**type** `google.bigquery.v1.FieldType` *required*

Mapped array of: Field type

```json CEL theme={null}
type
```

```json Example theme={null}
google.bigquery.v1.FieldType.STRING
google.bigquery.v1.FieldType.BYTES
google.bigquery.v1.FieldType.INTEGER
google.bigquery.v1.FieldType.FLOAT
google.bigquery.v1.FieldType.BOOLEAN
google.bigquery.v1.FieldType.TIMESTAMP
google.bigquery.v1.FieldType.RECORD
google.bigquery.v1.FieldType.DATE
google.bigquery.v1.FieldType.TIME
google.bigquery.v1.FieldType.DATETIME
google.bigquery.v1.FieldType.NUMERIC
google.bigquery.v1.FieldType.GEOGRAPHY
google.bigquery.v1.FieldType.BIGNUMERIC
google.bigquery.v1.FieldType.INTERVAL
google.bigquery.v1.FieldType.JSON
google.bigquery.v1.FieldType.RANGE
```

**table\_schema.map(x, x.repeated)** `[]bool` *required*

Mapped array of: If the field is a list

```json CEL theme={null}
$result_object_key.table_schema.map(x, x.repeated)
```

```json Example theme={null}
[
false
]
```

**table\_schema.map(x, x.required)** `[]bool` *required*

Mapped array of: If the field is required

```json CEL theme={null}
$result_object_key.table_schema.map(x, x.required)
```

```json Example theme={null}
[
true
]
```

**table\_schema.map(x, x.description)** `[]string` *required*

Mapped array of: Field description

```json CEL theme={null}
$result_object_key.table_schema.map(x, x.description)
```

```json Example theme={null}
[
"Number of visits of this patient"
]
```

**table\_schema.map(x, x.fields)** `[]bool` *required*

*Description coming soon*

```json CEL theme={null}
$result_object_key.table_schema.map(x, x.fields)
```

```json Example theme={null}
[
[
{
"description": "Number of visits of this patient",
"fields": null,
"name": "number_of_visits",
"repeated": false,
"required": true,
"type": "INTEGER"
}
]
]
```

**table\_name** `string` *required*

Table name used to save the data

```json CEL theme={null}
$result_object_key.table_name
```

```json Example theme={null}
"healthie_patient_updated"
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.