Usar bibliotecas de código aberto do Python

É possível usar bibliotecas Python de código aberto no BigQuery para processar dados, criar modelos de machine learning (ML) e gerenciar seus recursos de nuvem usando um código conhecido. Escolher a biblioteca certa para sua carga de trabalho pode ajudar você a escalonar com eficiência de linguagem de cliente leves para o processamento de terabytes de dados usando o mecanismo do lado do servidor do BigQuery.

Biblioteca Caso de uso Tamanho máximo dos dados Descrição
bigquery-dataframes Processamento de dados baseado em Python e operações de ML com processamento do lado do servidor Escalonável para conjuntos de dados de vários terabytes (pushdown do lado do servidor) APIs do Pandas e do scikit-learn implementadas com o pushdown do lado do servidor. Para mais informações, consulte Introdução ao BigQuery DataFrames.
pandas-gbq Processamento de dados baseado em Python usando uma cópia de dados do lado do cliente Limitado pela memória do cliente Permite mover dados de/para DataFrames do Python no lado do cliente. Para mais informações, consulte a documentação e o código-fonte.
google-cloud-bigquery Implantação, administração e consultas baseadas em SQL do BigQuery Limitado pela memória do cliente Pacote Python que une todas as APIs BigQuery. Para mais informações, consulte a documentação e o código-fonte.

Como usar BigQuery DataFrames, pandas-gbq e google-cloud-bigquery

A biblioteca BigQuery DataFrames (bigframes) fornece um DataFrame em Python e uma API de ML com processamento de consultas do lado do servidor. A biblioteca pandas-gbq fornece uma interface para executar consultas e fazer upload dos DataFrames do Pandas para o BigQuery. É um wrapper fino da biblioteca de cliente do BigQuery, google-cloud-bigquery.

Instalar as bibliotecas

Para usar os exemplos de código deste guia, instale os pacotes bigframes, pandas-gbq e google-cloud-bigquery:

pip install --upgrade bigframes pandas-gbq 'google-cloud-bigquery[bqstorage,pandas]'

Executar consultas

As três bibliotecas são compatíveis com a consulta de dados armazenados no BigQuery. As principais diferenças entre as bibliotecas incluem:

bigquery-dataframes pandas-gbq google-cloud-bigquery
Sintaxe SQL padrão GoogleSQL GoogleSQL (configurável com pandas_gbq.context.dialect) GoogleSQL
Configurações de consulta Configurável usando os parâmetros bpd.options.bigquery ou read_gbq Enviada como dicionário no formato de uma solicitação de consulta. Use a classe QueryJobConfig, que contém propriedades para as várias opções de configuração da API.

Consultar dados com a sintaxe GoogleSQL

Na amostra a seguir, mostramos como executar uma consulta do GoogleSQL com e sem a especificação explícita de um projeto. Nas três bibliotecas, se um projeto não for especificado, ele será determinado a partir das credenciais padrão.

bigquery-dataframes

import bigframes.pandas as bpd

# Set partial ordering mode for BigQuery DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_standard_sql(project_id: str = "your-project-id") -> bpd.DataFrame:
    """Runs a standard SQL query using BigQuery DataFrames."""
    sql = """
    SELECT name FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = 'TX'
    LIMIT 100
    """

    # Run a query alongside existing SQL. The project will be determined from
    # default credentials.
    df = bpd.read_gbq(sql)

    # Run a query after explicitly specifying a project.
    bpd.close_session()
    bpd.options.bigquery.project = project_id
    df = bpd.read_gbq(sql)
    return df


# Run the sample:
# df = query_standard_sql("your-project-id")
# print(df.head())

pandas-gbq

import pandas

sql = """
    SELECT name
    FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = 'TX'
    LIMIT 100
"""

# Run a Standard SQL query using the environment's default project
df = pandas.read_gbq(sql, dialect="standard")

# Run a Standard SQL query with the project set explicitly
project_id = "your-project-id"
df = pandas.read_gbq(sql, project_id=project_id, dialect="standard")

google-cloud-bigquery

from google.cloud import bigquery

client = bigquery.Client()
sql = """
    SELECT name
    FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = 'TX'
    LIMIT 100
"""

# Run a Standard SQL query using the environment's default project
df = client.query(sql).to_dataframe()

# Run a Standard SQL query with the project set explicitly
project_id = "your-project-id"
df = client.query(sql, project=project_id).to_dataframe()

Como consultar dados com a sintaxe SQL legada

No exemplo a seguir, mostramos como executar uma consulta usando a sintaxe SQL legada. Consulte o guia de migração do GoogleSQL para ver orientações sobre como atualizar suas consultas para o GoogleSQL.

bigquery-dataframes

O BigQuery DataFrames não é compatível com a sintaxe SQL legada. Use a sintaxe do GoogleSQL.

pandas-gbq

import pandas

sql = """
    SELECT name
    FROM [bigquery-public-data:usa_names.usa_1910_current]
    WHERE state = 'TX'
    LIMIT 100
"""

df = pandas.read_gbq(sql, dialect="legacy")

google-cloud-bigquery

from google.cloud import bigquery

client = bigquery.Client()
sql = """
    SELECT name
    FROM [bigquery-public-data:usa_names.usa_1910_current]
    WHERE state = 'TX'
    LIMIT 100
"""
query_config = bigquery.QueryJobConfig(use_legacy_sql=True)

df = client.query(sql, job_config=query_config).to_dataframe()

Como usar a API BigQuery Storage para fazer o download de resultados grandes

Use a API BigQuery Storage para acelerar os downloads de resultados grandes em 15 a 31 vezes.

bigquery-dataframes

import bigframes.pandas as bpd
import pandas as pd

# Set partial ordering mode for BigQuery DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_bqstorage() -> pd.DataFrame:
    """Queries BigQuery and downloads results using the BigQuery Storage API."""
    sql = """
    SELECT name FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = 'TX'
    LIMIT 100
    """

    # Read query results into a server-side DataFrame without downloading data.
    df = bpd.read_gbq(sql)

    # When downloading results to an in-memory pandas DataFrame,
    # bigquery-dataframes automatically uses the BigQuery Storage API if
    # installed.
    pandas_df = df.to_pandas()
    return pandas_df


# Run the sample:
# pandas_df = query_bqstorage()
# print(pandas_df.head())

pandas-gbq

import pandas

sql = "SELECT * FROM `bigquery-public-data.irs_990.irs_990_2012`"

# Use the BigQuery Storage API to download results more quickly.
df = pandas.read_gbq(sql, dialect="standard", use_bqstorage_api=True)

google-cloud-bigquery

from google.cloud import bigquery

client = bigquery.Client()
sql = "SELECT * FROM `bigquery-public-data.irs_990.irs_990_2012`"

# The client library uses the BigQuery Storage API to download results to a
# pandas dataframe if the API is enabled on the project, the
# `google-cloud-bigquery-storage` package is installed, and the `pyarrow`
# package is installed.
df = client.query(sql).to_dataframe()

Como executar uma consulta com uma configuração

O envio de uma configuração com uma solicitação de API BigQuery é necessário para executar determinadas operações complexas, como executar uma consulta parametrizada ou especificar uma tabela de destino para armazenar os resultados da consulta. No bigquery-dataframes (read_gbq) e no pandas-gbq, a configuração precisa ser enviada como um dicionário no formato de uma solicitação de consulta. No google-cloud-bigquery, são fornecidas classes de configuração de jobs, como QueryJobConfig, que contêm as propriedades necessárias para configurar jobs complexos.

A amostra a seguir mostra como executar uma consulta com parâmetros nomeados.

bigquery-dataframes

import bigframes.pandas as bpd

# Set partial ordering mode for BigQuery DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_parameters() -> bpd.DataFrame:
    """Queries BigQuery using BigQuery DataFrames with query parameters."""
    sql = """
    SELECT name FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = @state
    LIMIT 100
    """

    query_config = {
        "query": {
            "parameterMode": "NAMED",
            "queryParameters": [
                {
                    "name": "state",
                    "parameterType": {"type": "STRING"},
                    "parameterValue": {"value": "TX"},
                }
            ],
        }
    }

    df = bpd.read_gbq(sql, configuration=query_config)
    return df


# Run the sample:
# df = query_parameters()
# print(df.head())

pandas-gbq

import pandas

sql = """
    SELECT name
    FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = @state
    LIMIT @limit
"""
query_config = {
    "query": {
        "parameterMode": "NAMED",
        "queryParameters": [
            {
                "name": "state",
                "parameterType": {"type": "STRING"},
                "parameterValue": {"value": "TX"},
            },
            {
                "name": "limit",
                "parameterType": {"type": "INTEGER"},
                "parameterValue": {"value": 100},
            },
        ],
    }
}

df = pandas.read_gbq(sql, configuration=query_config)

google-cloud-bigquery

from google.cloud import bigquery

client = bigquery.Client()
sql = """
    SELECT name
    FROM `bigquery-public-data.usa_names.usa_1910_current`
    WHERE state = @state
    LIMIT @limit
"""
query_config = bigquery.QueryJobConfig(
    query_parameters=[
        bigquery.ScalarQueryParameter("state", "STRING", "TX"),
        bigquery.ScalarQueryParameter("limit", "INTEGER", 100),
    ]
)

df = client.query(sql, job_config=query_config).to_dataframe()

Como carregar um DataFrame do pandas para uma tabela do BigQuery

As três bibliotecas oferecem suporte ao upload de dados de um DataFrame do pandas para uma nova tabela no BigQuery. As principais diferenças incluem:

bigquery-dataframes pandas-gbq google-cloud-bigquery
Tipo de suporte Converte o DataFrame usando read_pandas e o grava em uma tabela usando to_gbq. Converte o formato DataFrame para CSV antes de enviar para a API, que não é compatível com valores aninhados ou de matriz. Converte o DataFrame em formato Parquet ou CSV antes de enviar para a API, que é compatível com valores aninhados e de matriz. Escolha Parquet para valores de estrutura e matriz e CSV para flexibilidade de serialização de data e hora. O Parquet é a escolha padrão. Observe que pyarrow, que é o mecanismo de parquet usado para enviar os dados do DataFrame para a API BigQuery, deve estar instalado para carregar o DataFrame em uma tabela.
Carregar configurações Configure o comportamento com parâmetros to_gbq, como if_exists. Também é possível especificar um esquema de tabela. Use a classe LoadJobConfig, que contém propriedades para as várias opções de configuração da API.

bigquery-dataframes

import bigframes.pandas as bpd
import pandas as pd

# Set partial ordering mode for BigQuery DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def upload_from_dataframe(
    table_id: str = "your-project.your_dataset.your_table_name",
) -> bpd.DataFrame:
    """Uploads an in-memory pandas DataFrame to a BigQuery table using BigQuery DataFrames."""
    # Create a local pandas DataFrame.
    df = pd.DataFrame(
        {
            "my_string": ["a", "b", "c"],
            "my_int64": [1, 2, 3],
            "my_float64": [4.0, 5.0, 6.0],
        }
    )

    # Convert the local pandas DataFrame to a BigQuery DataFrame.
    bq_df = bpd.read_pandas(df)

    # Write the DataFrame to a BigQuery table.
    bq_df.to_gbq(table_id, if_exists="replace")
    return bq_df


# Run the sample:
# bq_df = upload_from_dataframe("your-project.your_dataset.your_table_name")
# print(bq_df.head())

pandas-gbq

import pandas

df = pandas.DataFrame(
    {
        "my_string": ["a", "b", "c"],
        "my_int64": [1, 2, 3],
        "my_float64": [4.0, 5.0, 6.0],
        "my_timestamp": [
            pandas.Timestamp("1998-09-04T16:03:14"),
            pandas.Timestamp("2010-09-13T12:03:45"),
            pandas.Timestamp("2015-10-02T16:00:00"),
        ],
    }
)
table_id = "my_dataset.new_table"

df.to_gbq(table_id)

google-cloud-bigquery

O pacote google-cloud-bigquery requer que a biblioteca pyarrow serialize um DataFrame Pandas em um arquivo Parquet.

Instale o pacote pyarrow:

pip install pyarrow

from google.cloud import bigquery
import pandas

df = pandas.DataFrame(
    {
        "my_string": ["a", "b", "c"],
        "my_int64": [1, 2, 3],
        "my_float64": [4.0, 5.0, 6.0],
        "my_timestamp": [
            pandas.Timestamp("1998-09-04T16:03:14"),
            pandas.Timestamp("2010-09-13T12:03:45"),
            pandas.Timestamp("2015-10-02T16:00:00"),
        ],
    }
)
client = bigquery.Client()
table_id = "my_dataset.new_table"
# Since string columns use the "object" dtype, pass in a (partial) schema
# to ensure the correct BigQuery data type.
job_config = bigquery.LoadJobConfig(
    schema=[
        bigquery.SchemaField("my_string", "STRING"),
    ]
)

job = client.load_table_from_dataframe(df, table_id, job_config=job_config)

# Wait for the load job to complete.
job.result()

Recursos não compatíveis com pandas-gbq e bigquery-dataframes

Embora as bibliotecas pandas-gbq e bigquery-dataframes forneçam interfaces úteis para consultar dados e gravar dados em tabelas, elas não abrangem muitos dos recursos da API BigQuery, incluindo, entre outros:

Como solucionar erros do pool de conexão

String de erro: Connection pool is full, discarding connection: bigquery.googleapis.com. Connection pool size: 10

Se você usar o objeto do cliente padrão do BigQuery em Python, o limite será de 10 linhas de execução, já que o tamanho padrão do pool do Python HTTPAdapter é 10. Para usar mais de 10 conexões, crie um objeto requests.adapters.HTTPAdapter personalizado. Exemplo:

client = bigquery.Client()
adapter = requests.adapters.HTTPAdapter(pool_connections=128,
pool_maxsize=128,max_retries=3)
client._http.mount("https://",adapter)
client._http._auth_request.session.mount("https://",adapter)
query_job = client.query(QUERY)