שימוש בספריות Python בקוד פתוח

אתם יכולים לבחור מבין שלוש ספריות Python ב-BigQuery, בהתאם לתרחיש השימוש שלכם.

תרחיש שימוש גודל נתונים מקסימלי תיאור
bigquery-dataframes עיבוד נתונים ותפעול ML מבוססי Python עם עיבוד בצד השרת ניתן להרחבה למערכי נתונים של כמה טרה-בייט (העברת נתונים לצד השרת) ממשקי API של Pandas ו-scikit-learn שהוטמעו באמצעות דחיפה לצד השרת. למידע נוסף, קראו את המאמר מבוא ל-BigQuery DataFrames.
pandas-gbq עיבוד נתונים מבוסס Python באמצעות העתקת נתונים בצד הלקוח מוגבל על ידי זיכרון הלקוח מאפשר להעביר נתונים אל ומ-Python DataFrames בצד הלקוח. מידע נוסף זמין במסמכי התיעוד ובקוד המקור.
google-cloud-bigquery פריסה, ניהול ושאילתות מבוססות SQL ב-BigQuery מוגבל על ידי זיכרון הלקוח חבילת Python שעוטפת את כל ממשקי BigQuery API. מידע נוסף זמין במסמכי התיעוד ובקוד המקור.

שימוש ב-BigQuery DataFrames, ב-pandas-gbq וב-google-cloud-bigquery

ספריית BigQuery DataFrames ‏ (bigframes) מספקת DataFrame ו-ML API בסגנון Python עם עיבוד שאילתות בצד השרת. ספריית pandas-gbq מספקת ממשק פשוט להרצת שאילתות ולהעלאת מסגרות נתונים של pandas ל-BigQuery. הוא עוטף את ספריית הלקוח של BigQuery,‏ google-cloud-bigquery.

התקנת הספריות

כדי להשתמש בדוגמאות הקוד במדריך הזה, צריך להתקין את החבילות bigframes, pandas-gbq ו-google-cloud-bigquery:

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

הרצת שאילתות

כל שלוש הספריות תומכות בביצוע שאילתות על נתונים שמאוחסנים ב-BigQuery. ההבדלים העיקריים בין הספריות כוללים:

bigquery-dataframes pandas-gbq google-cloud-bigquery
תחביר SQL שמוגדר כברירת מחדל GoogleSQL ‫GoogleSQL (ניתן להגדרה באמצעות pandas_gbq.context.dialect) GoogleSQL
הגדרות שאילתה אפשר להגדיר באמצעות פרמטרים של bpd.options.bigquery או read_gbq נשלח כמילון בפורמט של בקשת שאילתה. משתמשים במחלקה QueryJobConfig, שמכילה מאפיינים לאפשרויות השונות של הגדרת ה-API.

שליחת שאילתות לנתונים באמצעות התחביר של GoogleSQL

בדוגמה הבאה אפשר לראות איך להריץ שאילתת GoogleSQL עם ציון פרויקט וגם בלי ציון פרויקט. בכל שלוש הספריות, אם לא מציינים פרויקט, הפרויקט ייקבע לפי פרטי הכניסה שמוגדרים כברירת מחדל.

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

ביצוע שאילתות על נתונים באמצעות תחביר SQL מדור קודם

בדוגמה הבאה אפשר לראות איך מריצים שאילתה באמצעות תחביר SQL מדור קודם. במדריך להעברת נתונים ל-GoogleSQL יש הוראות לעדכון השאילתות ל-GoogleSQL.

bigquery-dataframes

‫BigQuery DataFrames לא תומך בתחביר של SQL מדור קודם. במקום זאת, צריך להשתמש בתחביר של 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()

שימוש ב-BigQuery Storage API להורדת תוצאות גדולות

אתם יכולים להשתמש ב-BigQuery Storage API כדי להוריד תוצאות גדולות במהירות גבוהה פי 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()

הרצת שאילתה עם הגדרה

כדי לבצע פעולות מורכבות מסוימות, כמו הפעלת שאילתה עם פרמטרים או ציון טבלת יעד לאחסון תוצאות השאילתה, צריך לשלוח הגדרה עם בקשת BigQuery API. ב-bigquery-dataframes ‏ (read_gbq) וב-pandas-gbq, צריך לשלוח את ההגדרה כמילון בפורמט של בקשת שאילתה. ב-google-cloud-bigquery, יש מחלקות הגדרות של משימות, כמו QueryJobConfig, שמכילות את המאפיינים הדרושים להגדרת משימות מורכבות.

בדוגמה הבאה אפשר לראות איך מריצים שאילתה עם פרמטרים בעלי שמות.

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

טעינת pandas DataFrame לטבלה ב-BigQuery

כל שלוש הספריות תומכות בהעלאת נתונים מ-pandas DataFrame לטבלה חדשה ב-BigQuery. ההבדלים העיקריים כוללים:

bigquery-dataframes pandas-gbq google-cloud-bigquery
סוג התמיכה הפונקציה ממירה את pandas DataFrame המקומי ל-bigframes.pandas.DataFrame באמצעות read_pandas (באמצעות Parquet או CSV מתחת לפני השטח), עם תמיכה בערכים מקוננים ובערכי מערך. אחר כך שומרים אותו בטבלה עם to_gbq. הפונקציה ממירה את DataFrame לפורמט CSV לפני השליחה ל-API, שלא תומך בערכים מקוננים או בערכי מערך. הפונקציה ממירה את DataFrame לפורמט Parquet או CSV לפני השליחה ל-API, שתומך בערכים מקוננים ובערכי מערך. בוחרים ב-Parquet לערכי struct ומערך, וב-CSV לערכי תאריך ושעה כדי לקבל גמישות בסריאליזציה. Parquet היא ברירת המחדל. שימו לב שצריך להתקין את pyarrow, מנוע ה-parquet שמשמש לשליחת נתוני ה-DataFrame אל BigQuery API, כדי לטעון את ה-DataFrame לטבלה.
טעינת הגדרות משתמשים בפרמטר if_exists ('fail',‏ 'replace' או 'append') כששומרים עם to_gbq. אפשר גם לציין סכימת טבלה. משתמשים במחלקה LoadJobConfig, שמכילה מאפיינים לאפשרויות השונות של הגדרת ה-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

החבילה google-cloud-bigquery דורשת את הספרייה pyarrow כדי לבצע סריאליזציה של pandas DataFrame לקובץ Parquet.

מתקינים את חבילת 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()

תכונות שלא נתמכות על ידי pandas-gbq ו-bigquery-dataframes

ספריות pandas-gbq ו-bigquery-dataframes מספקות ממשקים שימושיים לשליחת שאילתות לגבי נתונים ולכתיבת נתונים לטבלאות, אבל הן לא כוללות הרבה מהתכונות של BigQuery API, כולל, בין היתר:

פתרון בעיות בחיבורים

מחרוזת שגיאה: Connection pool is full, discarding connection: bigquery.googleapis.com. Connection pool size: 10

אם משתמשים באובייקט ברירת המחדל של לקוח BigQuery ב-Python, אפשר להשתמש ב-10 שרשורים לכל היותר, כי גודל ברירת המחדל של מאגר השרשורים ב-Python HTTPAdapter הוא 10. כדי להשתמש ביותר מ-10 חיבורים, צריך ליצור אובייקט מותאם אישית requests.adapters.HTTPAdapter לדוגמה:

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)