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

# BigQuery

# Connector Details

| Name           | Value                                                                                                                                                                                                                                                                                                             |
| :------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Platform       | [BigQuery](https://cloud.google.com/bigquery)                                                                                                                                                                                                                                                                     |
| Auth Type      | API Keys                                                                                                                                                                                                                                                                                                          |
| Direction      | Bidirectional                                                                                                                                                                                                                                                                                                     |
| Tap Repo       | [https://gitlab.com/hotglue/tap-bigquery](https://gitlab.com/hotglue/tap-bigquery)                                                                                                                                                                                                                                |
| Target Repo    | [https://github.com/hotgluexyz/target-bigquery](https://github.com/hotgluexyz/target-bigquery)                                                                                                                                                                                                                    |
| Tap Metrics    | <p>Usage: <Tooltip tip="medium"><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#A9A9A9" size="14px" /></Tooltip></p> |
| Target Metrics | <p>Usage: <Tooltip tip="high"><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#fff" size="14px" /><Icon icon="user" iconType="regular" color="#fff" size="14px" /></Tooltip></p>      |

# Credentials Setup

Follow the steps below to get the credentials you need to use the BigQuery connector.

# How to get your BigQuery credentials

## Enable the BigQuery API

First and foremost, make sure you are logged in to the correct Google account that you would like to access BigQuery from. Once you're logged in to the correct Google account, head to the [Google Cloud Platfrom Web Console](https://console.cloud.google.com).

Once you are on the home page of GCP's Web Console, head to the navigation bar on the left side of the screen. Once you open the Navigation bar, head to the **APIs & Services** tab, and select **Library** from the resulting drop down.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR4jrLF1XzGtaGs7Fu%2F-MeRN_XEJkL-Xj7bVGI1%2F01_API_and_Services_Library-2.png?alt=media\&token=0bd4693f-3542-449a-b30a-75c71d7eb4c8)

This will take you to a page where you should input **BigQuery** in the search box. Once it pops up, go ahead and click on it.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeR4jrLF1XzGtaGs7Fu%2F-MeRN_XEJkL-Xj7bVGI1%2F01_API_and_Services_Library-2.png?alt=media\&token=0bd4693f-3542-449a-b30a-75c71d7eb4c8)

Now, go ahead and click the **Enable** button in order to enable the **BigQuery API**.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRQIJDsd3xHB8BGS0x%2F-MeRQceczcj_pQDp_ywp%2F03_Enable_BigQuery_API.png?alt=media\&token=58b4224f-a4c3-4e3a-942e-1868c0ff3f76)

## Authenticating with a service account

It is recomended that you use a service account with the BigQuery target. To create service account credentials, take the following steps.

Use the navigation bar on the left again to navigate to the **APIs & Services** tab and select **Credentials** from the resulting drop down menu. Once you are on the **Credentials** page, click the **Create Credentials** button at the top of the page, which will trigger a drop down menu. From that drop down menu, go ahead and select **Service Account**.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRQIJDsd3xHB8BGS0x%2F-MeRSBjlrbp42HlXuTtc%2F04_Create_Service_Account.png?alt=media\&token=b27c056e-0623-4b60-ac4b-9b107198ed07)

Under the **Service account details**, title the account target-bigquery and click the **Create** button.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRbhk7tu9Uk7KAoGqZ%2F-MeRc3GAYeMJMpbBpoTE%2F05_Service_Account_Name.png?alt=media\&token=0bee84cd-0641-4d7d-b9f8-7c341804fe33)

Under **Grant this service account access to project**, make sure that you have two roles. The first role should allow the service account to be a **BigQuery Data Editor**. This allows the target to edit the contents of the data sets (write permissions). Make sure that the second role is **BigQuery Job User**. This is a bit self explanatory, it allows the target to run jobs.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRdE7L-BH3ht-4EAd0%2F-MeRdxQeRdiNBZLlK3UK%2F06_Service_Account_Access.png?alt=media\&token=e36dc8e8-56d1-4b4b-9008-af6279e05b8a)

Now, using the navigation panel again, head back to the APIs & Services tab and go the **Credentials** tab within the tab. You should see the service account you just created near the bottom of your screen. Go and click on it.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRdE7L-BH3ht-4EAd0%2F-MeRfEmEYQKx0fXOmzjh%2F07_Select_Service_Account.png?alt=media\&token=9fe39905-51d3-4621-9b41-9f7e86918516)

Near the bottom of the page, you should go ahead and click the **Add Key** button which will prompt a dropdown. Once it does this, click **Create new key**.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfUXUohmqNW2TnCoh%2F-MeRffxvRy-Eu9BcPInT%2F08_Add_Key.png?alt=media\&token=4a9d82c7-e71c-46fc-b4c8-81bb5b3b5eaf)

Select **JSON** for your private key and click **Create**.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfsTfG__nJ-keqfi-%2F-MeRfxtnTHBxYydBBNLl%2F09_JSON_Key.png?alt=media\&token=5b2ecbdc-f684-40e8-b3ac-220b7780a93c)

You should go ahead and open the file. Make sure you keep this somewhere safe. This file holds the credentials that you should use to connect your BigQuery account as a target in hotglue.

![](https://files.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-M7i2HnOOnCAsbZRzd0G%2F-MeRfsTfG__nJ-keqfi-%2F-MeRg80uEKs3wsYmoGyw%2F10_Download_Client_Secrets.png?alt=media\&token=79998205-86fe-475d-89eb-50284362247a)

These are the credentials that are relevant for configuring your hotglue target. Paste them into their corresponding places in hotglue and you are all set!

```json theme={null}
{
  "type": "service_account",
  "project_id": "acme",
  "private_key_id": "1**********************************f",
  "private_key": "-----BEGIN PRIVATE KEY-----\n*************\n*****************************\n************************n/*************************\n******************************\n*************************\n************************************\n*******************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n-----END PRIVATE KEY-----\n",
  "client_email": "***********@acme.iam.gserviceaccount.com",
  "client_id": "1************7",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/**************image
    40acme.iam.gserviceaccount.com"
}
```

# Target BigQuery

## Config

In addition to the BigQuery credentials above, you will need to specify the dataset the target should write to:

```json theme={null}
{
  "type": "service_account",
  "project_id": "acme",
  "private_key_id": "1**********************************f",
  "private_key": "-----BEGIN PRIVATE KEY-----\n*************\n*****************************\n************************n/*************************\n******************************\n*************************\n************************************\n*******************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n**********************************\n-----END PRIVATE KEY-----\n",
  "client_email": "***********@acme.iam.gserviceaccount.com",
  "client_id": "1************7",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/**************image
    40acme.iam.gserviceaccount.com",
  "dataset_id": "id-of-dataset"
}
```

## target-tables-config: Set up partioning and clustering

Target-BigQuery also supports an optional `target-tables-config.json` which can be written during the ETL phase.
The config allows you to detail partioning and clustering logic for particular streams.

### Partitioning background

A [partitioned table](https://cloud.google.com/bigquery/docs/partitioned-tables) is a special table that is divided into
segments, called partitions, that make it easier to manage and query your data. By dividing a large table into smaller
partitions, you can:

* improve query performance,
* control costs by reducing the number of bytes read by a query.

You can partition BigQuery tables by:

* Ingestion time: Tables are partitioned based on the data's ingestion (load) time or arrival time.

* Date/timestamp/datetime: Tables are partitioned based on a TIMESTAMP, DATE, or DATETIME column.

* Integer range: Tables are partitioned based on an integer column.

### Clustering background

* When you create a clustered table in BigQuery, the table data is automatically organized based on the contents of one
  or more columns in the table’s schema.
* The columns you specify are used to colocate related data.
* When you cluster a table using multiple columns, the order of columns you specify is important. The order of the
  specified columns determines the sort order of the data.
* Clustering can improve the performance of certain types of queries such as queries that use filter clauses and queries
  that aggregate data.
* You can cluster up to 4 columns in a table

### Replication Methods

There is also an optional parameter `replication_method` which can be used to determine the upserting behavior for a particular stream.

Possible values are:

* `append`: Adding new rows to the table (Default value)
* `truncate`: Deleting all previous rows and uploading the new ones to the table
* `incremental`: **Upserting** new rows into the table, using the **primary key** given by the tap connector
  (if it finds an old row with same key, updates it. Otherwise it inserts the new row)

### Example `target-tables-config.json`

To add partioning and clustering to a given stream, you can specify the `partition_field` and `cluster_fields` values respectively.

```json theme={null}
{
  "streams": {
      "contacts": {
        "partition_field": "updated_at",
        "cluster_fields": ["type", "status", "customer_id", "transaction_id"]
      },
      "companies": {
        "replication_method": "truncate"
      }
  }
}
```

## Example ETL Script

```python theme={null}
import gluestick as gs
import os

# Define standard Hotglue directories
ROOT_DIR = os.environ.get("ROOT_DIR", ".")
INPUT_DIR = f"{ROOT_DIR}/sync-output"
OUTPUT_DIR = f"{ROOT_DIR}/etl-output"


# Write a target target-tables-config if desired
with open(f"{OUTPUT_DIR}/target-tables-config.json", "w") as fp:
    json.dump(
        {
            "streams": {
                "GeneralLedgerCashReport_default": {"replication_method": "truncate"},
                "BalanceSheetReport": {"replication_method": "truncate"},
                "CashFlowReport": {"replication_method": "truncate"},
                "DailyCashFlowReport": {"replication_method": "truncate"},
            }
        },
        fp,
    )


# Read sync output
input = gs.Reader()

# Get tenant id
tenant_id = os.environ.get('USER_ID', os.environ.get('TENANT', 'default'))

# Iterate through the different streams in the sync output
for key in eval(str(input)):
    input_df = input.get(key)

    """
    Here we get the key properties, also known as the primary keys.
    The database export targets will utilize these primary keys when upserting data.
    If you wish to hardcode your choice of primary keys, you can do so here.
    """
    key_properties = input.get_pk(key)

    # Include tenant_id as a field if desired
    input_df["tenant"] = tenant_id

    # Write this stream to the OUTPUT directory with the specified key_properties
    gs.to_singer(input_df, key, OUTPUT_DIR, keys=key_properties)
```

## Optional config flags

| Property                          | Type    | Description                                                                                     |
| --------------------------------- | ------- | ----------------------------------------------------------------------------------------------- |
| table\_suffix                     | String  | Suffix to be added to the table name.                                                           |
| validate\_records                 | Boolean | If true, validates records before loading.                                                      |
| add\_metadata\_columns            | Boolean | If true, adds metadata columns to the table.                                                    |
| location                          | String  | Specifies the location where the data will be stored. Default is "US".                          |
| replication\_method               | String  | Method for replicating data. Options: `append`, `truncate`, `incremental`. Default is `append`. |
| max\_cache                        | Integer | Maximum number of records to cache before writing to BigQuery.                                  |
| merge\_state\_messages            | Boolean | If true, merges state messages.                                                                 |
| force\_alphanumeric\_table\_names | String  | If true, replaces all non-alphanumeric characters in table names with `_`                       |

# Target Changelog

<Accordion title="Target Changelog">
  | Version                                                                         | Notes                |
  | :------------------------------------------------------------------------------ | :------------------- |
  | [v0.11.10](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.10) |                      |
  | [v0.11.9](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.9)   |                      |
  | [v0.11.8](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.8)   |                      |
  | [v0.11.7](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.7)   |                      |
  | [v0.11.6](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.6)   |                      |
  | [v0.11.5](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.5)   |                      |
  | [v0.11.4](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.4)   |                      |
  | [v0.11.3](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.3)   | fix infinite support |
  | [v0.11.2](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.2)   |                      |
  | [v0.11.1](https://github.com/hotgluexyz/target-bigquery/releases/tag/v0.11.1)   |                      |
</Accordion>
