Utiliser des bibliothèques Python Open Source

Vous avez le choix entre trois bibliothèques Python dans BigQuery, en fonction de votre cas d'utilisation.

Cas d'utilisation Taille maximale des données Description
bigquery-dataframes Traitement des données basé sur Python et opérations de ML avec traitement côté serveur Évolutivité pour les ensembles de données de plusieurs téraoctets (transfert côté serveur) API pandas et scikit-learn implémentées avec pushdown côté serveur. Pour plus d'informations, consultez la page Présentation des objets BigQuery DataFrame.
pandas-gbq Traitement des données Python à l'aide de la copie de données côté client Mémoire client limitée Permet de déplacer des données vers et depuis des objets Python DataFrame côté client. Pour en savoir plus, consultez la documentation et le code source.
google-cloud-bigquery Déploiement de BigQuery, administration et requêtes basées sur SQL Mémoire client limitée Package Python encapsulant toutes les API BigQuery. Pour en savoir plus, consultez la documentation et le code source.

Utiliser BigQuery DataFrames, pandas-gbq et google-cloud-bigquery

La bibliothèque BigQuery DataFrames (bigframes) fournit un DataFrame Python et une API de ML avec traitement des requêtes côté serveur. La bibliothèque pandas-gbq fournit une interface simple pour exécuter des requêtes et importer des DataFrames pandas dans BigQuery. Il s'agit d'un wrapper de bas niveau autour de la bibliothèque cliente BigQuery, google-cloud-bigquery.

Installer les bibliothèques

Pour utiliser les exemples de code de ce guide, installez les packages bigframes, pandas-gbq et google-cloud-bigquery :

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

Exécution de requêtes

Les trois bibliothèques permettent d'interroger les données stockées dans BigQuery. Les principales différences qui les distinguent sont présentées ci-dessous.

bigquery-dataframes pandas-gbq google-cloud-bigquery
Syntaxe SQL par défaut GoogleSQL GoogleSQL (configurable avec pandas_gbq.context.dialect) GoogleSQL
Configurations de requêtes Configurable à l'aide des paramètres bpd.options.bigquery ou read_gbq Envoyées sous forme de dictionnaire au format d'une requête. Possibilité d'utiliser la classe QueryJobConfig, qui contient les propriétés des différentes options de configuration de l'API.

Interroger des données avec une syntaxe en GoogleSQL

L'exemple ci-dessous montre comment exécuter une requête GoogleSQL en indiquant de façon explicite un projet ou sans le spécifier. Pour les trois bibliothèques, si vous ne spécifiez aucun projet, il sera déterminé à partir des identifiants par défaut.

bigquery-dataframes

import bigframes.pandas as bpd

# Set partial ordering mode as the default configuration for BigQuery
# DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_standard_sql(project_id: str = "your-project-id") -> bpd.DataFrame:
    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

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

Interroger des données avec une syntaxe en ancien SQL

L'exemple ci-dessous montre comment exécuter une requête à l'aide d'une syntaxe en ancien SQL. Consultez le guide de migration vers le langage GoogleSQL pour savoir comment mettre à jour vos requêtes en GoogleSQL.

bigquery-dataframes

BigQuery DataFrames n'accepte pas la syntaxe de l'ancien SQL. Utilisez plutôt la syntaxe 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()

Télécharger des résultats volumineux à l'aide de l'API BigQuery Storage

L'API BigQuery Storage vous permet de multiplier la vitesse de téléchargement des résultats volumineux par 15 à 31.

bigquery-dataframes

import bigframes.pandas as bpd

import pandas as pd

# Set partial ordering mode as the default configuration for BigQuery
# DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_bqstorage() -> pd.DataFrame:
    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

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

Exécuter une requête avec une configuration

L'envoi d'une configuration avec une requête d'API BigQuery est nécessaire pour effectuer certaines opérations complexes, telles que l'exécution d'une requête paramétrée ou la spécification d'une table de destination permettant de stocker les résultats de requête. Dans bigquery-dataframes (read_gbq) et pandas-gbq, la configuration doit être envoyée sous forme de dictionnaire au format d'une requête. google-cloud-bigquery fournit des classes de configuration de tâche telles que QueryJobConfig, qui contiennent les propriétés nécessaires à la configuration de tâches complexes.

L'exemple ci-dessous montre comment exécuter une requête avec des paramètres nommés.

bigquery-dataframes

import bigframes.pandas as bpd

# Set partial ordering mode as the default configuration for BigQuery
# DataFrames.
bpd.options.bigquery.ordering_mode = "partial"


def query_parameters() -> bpd.DataFrame:
    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

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

Charger un objet DataFrame pandas dans une table BigQuery

Les trois bibliothèques permettent d'importer les données d'un DataFrame pandas dans une nouvelle table BigQuery. Les principales différences qui les distinguent sont décrites ci-dessous.

bigquery-dataframes pandas-gbq google-cloud-bigquery
Formats compatibles Convertit le DataFrame pandas local en bigframes.pandas.DataFrame à l'aide de read_pandas (en utilisant Parquet ou CSV en arrière-plan), en acceptant les valeurs imbriquées et de tableau. Vous l'enregistrez ensuite dans un tableau avec to_gbq. Convertit l'objet DataFrame au format CSV avant de l'envoyer à l'API, qui n'accepte pas les valeurs imbriquées ou de tableau. Convertit l'objet DataFrame au format Parquet ou CSV avant de l'envoyer à l'API, qui accepte les valeurs imbriquées ou de tableau. Choisissez Parquet pour les valeurs de structure et de tableau, et CSV pour la flexibilité de sérialisation des dates et heures. Parquet est le choix par défaut. Notez que pyarrow, qui est le moteur Parquet utilisé pour envoyer les données DataFrame à l'API BigQuery, doit être installé pour permettre le chargement de l'objet DataFrame dans une table.
Configurations de chargement Utilisez le paramètre if_exists ('fail', 'replace' ou 'append') lorsque vous enregistrez avec to_gbq. Vous pouvez éventuellement spécifier un schéma de table. Possibilité d'utiliser la classe LoadJobConfig, qui contient les propriétés des différentes options de configuration de l'API.

bigquery-dataframes

import bigframes.pandas as bpd

import pandas as pd

# Set partial ordering mode as the default configuration 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:
    # 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

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

Le package google-cloud-bigquery nécessite la bibliothèque pyarrow pour sérialiser un objet DataFrame pandas en fichier Parquet.

Installez le package 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()

Fonctionnalités non disponibles avec pandas-gbq et bigquery-dataframes

Même si les bibliothèques pandas-gbq et bigquery-dataframes fournissent des interfaces utiles pour interroger et écrire des données dans des tables, il leur manque de nombreuses fonctionnalités offertes par l'API BigQuery, parmi lesquelles :

Résoudre les erreurs de pool de connexions

Chaîne d'erreur : Connection pool is full, discarding connection: bigquery.googleapis.com. Connection pool size: 10

Si vous utilisez l'objet client BigQuery par défaut dans Python, vous êtes limité à un maximum de 10 threads, car la taille du pool par défaut pour Python HTTPAdapter est de 10. Pour utiliser plus de 10 connexions, créez un objet requests.adapters.HTTPAdapter personnalisé. Par exemple :

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)