Elegir una biblioteca de Python

En BigQuery, puedes elegir entre tres bibliotecas de Python en función de tu caso práctico.

Caso práctico Mantenido por Descripción
BigQuery DataFrames Procesamiento de datos y operaciones de aprendizaje automático basados en Python con procesamiento del lado del servidor (por ejemplo, mediante el uso de slots) Google APIs de Pandas y Scikit-learn implementadas con la función de envío al lado del servidor. Para obtener más información, consulta Introducción a BigQuery DataFrames.
pandas-gbq Procesamiento de datos basado en Python mediante la copia de datos del lado del cliente Biblioteca de código abierto mantenida por PyData y colaboradores voluntarios Te permite mover datos a y desde DataFrames de Python en el lado del cliente. Para obtener más información, consulta la documentación y el código fuente.
google-cloud-bigquery Implementación, administración y consultas basadas en SQL de BigQuery Biblioteca de código abierto mantenida por Google Paquete de Python que encapsula todas las APIs de BigQuery. Para obtener más información, consulta la documentación y el código fuente.

Usar pandas-gbq y google-cloud-bigquery

La biblioteca pandas-gbq proporciona una interfaz sencilla para ejecutar consultas y subir dataframes de pandas a BigQuery. Es un envoltorio ligero de la biblioteca de cliente de BigQuery, google-cloud-bigquery. Ambas bibliotecas se centran en ayudarte a realizar análisis de datos con SQL.

Instalar las bibliotecas

Para usar los ejemplos de código de esta guía, instala el paquete pandas-gbq y las bibliotecas de cliente de Python de BigQuery.

Instala los paquetes pandas-gbq y google-cloud-bigquery.

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

Cómo ejecutar consultas

Ambas bibliotecas permiten consultar datos almacenados en BigQuery. Entre las principales diferencias entre las bibliotecas se incluyen las siguientes:

pandas-gbq google-cloud-bigquery
Sintaxis de SQL predeterminada GoogleSQL (configurable con pandas_gbq.context.dialect) GoogleSQL
Configuraciones de consultas Se envía como diccionario en el formato de una solicitud de consulta. Usa la clase QueryJobConfig, que contiene propiedades para las distintas opciones de configuración de la API.

Consultar datos con la sintaxis de GoogleSQL

En el siguiente ejemplo se muestra cómo ejecutar una consulta de GoogleSQL especificando y sin especificar explícitamente un proyecto. En ambas bibliotecas, si no se especifica ningún proyecto, se determinará a partir de las credenciales predeterminadas.

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()

Consultar datos con la sintaxis de SQL antiguo

En el siguiente ejemplo se muestra cómo ejecutar una consulta con la sintaxis de SQL antiguo. Consulta la guía de migración a GoogleSQL para obtener información sobre cómo actualizar tus consultas a 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()

Usar la API Storage de BigQuery para descargar resultados de gran tamaño

Usa la API Storage de BigQuery para acelerar las descargas de resultados de gran tamaño entre 15 y 31 veces.

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()

Ejecutar una consulta con una configuración

Es necesario enviar una configuración con una solicitud a la API de BigQuery para realizar determinadas operaciones complejas, como ejecutar una consulta parametrizada o especificar una tabla de destino para almacenar los resultados de la consulta. En pandas-gbq, la configuración debe enviarse como un diccionario con el formato de una solicitud de consulta. En google-cloud-bigquery, se proporcionan clases de configuración de trabajos, como QueryJobConfig, que contienen las propiedades necesarias para configurar trabajos complejos.

En el siguiente ejemplo se muestra cómo ejecutar una consulta con parámetros con nombre.

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()

Cargar un DataFrame de pandas en una tabla de BigQuery

Ambas bibliotecas permiten subir datos de un DataFrame de pandas a una tabla nueva de BigQuery. Entre las principales diferencias se incluyen las siguientes:

pandas-gbq google-cloud-bigquery
Asistencia para escribir Convierte el DataFrame al formato CSV antes de enviarlo a la API, que no admite valores anidados ni de matriz. Convierte el DataFrame al formato Parquet o CSV antes de enviarlo a la API, que admite valores anidados y de matriz. Elige Parquet para los valores de struct y array, y CSV para la flexibilidad de serialización de fechas y horas. Parquet es la opción predeterminada. Ten en cuenta que pyarrow, que es el motor de Parquet que se usa para enviar los datos de DataFrame a la API de BigQuery, debe estar instalado para cargar el DataFrame en una tabla.
Cargar configuraciones También puedes especificar un esquema de tabla. Usa la clase LoadJobConfig, que contiene propiedades para las distintas opciones de configuración de la API.

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:

El paquete google-cloud-bigquery requiere la biblioteca pyarrow para serializar un DataFrame de pandas en un archivo Parquet.

Instala el paquete 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()

Funciones no compatibles con pandas-gbq

Aunque la biblioteca pandas-gbq proporciona una interfaz útil para consultar datos y escribir datos en tablas, no abarca muchas de las funciones de la API de BigQuery, entre las que se incluyen las siguientes:

Solucionar errores del grupo de conexiones

Error string: Connection pool is full, discarding connection: bigquery.googleapis.com. Connection pool size: 10

Si usas el objeto de cliente predeterminado de BigQuery en Python, solo podrás usar un máximo de 10 hilos, ya que el tamaño predeterminado del grupo de Python HTTPAdapter es 10. Para usar más de 10 conexiones, crea un requests.adapters.HTTPAdapter objeto personalizado. Por ejemplo:

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)