pip install "google-cloud-bigquery[pandas]"★The[pandas]extra adds DataFrame support; addbigquery-storagefor fast reads (card 11). Python 3.10+.gcloud auth application-default login # local dev auth★Sets up Application Default Credentials. On GCP (Cloud Run/GCE/GKE) the attached service account is used automatically.from google.cloud import bigquery client = bigquery.Client(project="my-project")★The client.projectis the billing project.Client.from_service_account_json("key.json")for an explicit key.client = bigquery.Client(project="p", location="US")Set the dataset location (region) to avoid "dataset not found" errors on non-US data.
job = client.query("SELECT name, count FROM `p.ds.t` LIMIT 10") rows = job.result() # waits for completion★query()starts an async QueryJob immediately;.result()blocks until done and returns aRowIterator. Backtick-quote`project.dataset.table`.for row in rows: print(row.name, row.count, row["count"])★Rows support attribute and key access.dict(row)to convert.df = client.query_and_wait(sql).to_dataframe()★3.xquery_and_wait()is the newer one-call helper (run + wait) — returns the RowIterator directly.job.total_bytes_processed · job.job_id · job.stateInspect the job: bytes billed, id (to fetch later withclient.get_job), and state.
from google.cloud import bigquery cfg = bigquery.QueryJobConfig(query_parameters=[ bigquery.ScalarQueryParameter("min", "INT64", 100)]) client.query("SELECT * FROM t WHERE n > @min", job_config=cfg)★Always parameterize user input with@nameplaceholders — safe against injection. Never f-string values into SQL.bigquery.ArrayQueryParameter("ids", "INT64", [1,2,3])Array & struct parameters too. Use@idswithUNNEST(@ids)orn IN UNNEST(@ids).cfg = bigquery.QueryJobConfig( default_dataset="p.ds", use_query_cache=True)QueryJobConfigcarries all query options: default dataset (skip qualifying tables), cache, priority, labels, destination.