Pydantic-based BigQuery client for type-safe schema definition and data operations
Project description
pydantic-bq
A Pydantic-based BigQuery client for type-safe schema definition and data operations.
Installation
pip install pydantic-bq
Or with uv:
uv add pydantic-bq
Quick Start
1. Configure Credentials
Create a .env file with your BigQuery credentials:
# Option 1: Base64-encoded service account JSON (recommended)
BIGQUERY_CREDENTIALS=eyJ0eXBlIjoic2VydmljZV9hY2NvdW50Ii...
# Option 2: Individual fields
G_PROJECT_ID=your-project-id
G_CLIENT_EMAIL=service-account@your-project.iam.gserviceaccount.com
G_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
...your key here...
-----END PRIVATE KEY-----"
2. Define a Model
from datetime import datetime
from typing import Optional
from pydantic_bq import BQBaseModel
class UserEvent(BQBaseModel):
user_id: int
event_type: str
timestamp: datetime
metadata: Optional[str] = None
class Meta:
table_id = 'user_events'
table_description = 'User activity events'
3. Connect and Query
from pydantic_bq import DatasetClient
# Uses credentials from environment/.env automatically
client = DatasetClient('my_dataset')
# Query rows as Pydantic objects
events = client.table(UserEvent).get_rows(
where="event_type = 'login'",
limit=100
)
for event in events:
print(f"User {event.user_id} logged in at {event.timestamp}")
4. Insert Data
from datetime import datetime
# Create new events
new_events = [
UserEvent(user_id=1, event_type='signup', timestamp=datetime.now()),
UserEvent(user_id=2, event_type='login', timestamp=datetime.now()),
]
# Insert into BigQuery
client.table(UserEvent).add_rows(*new_events)
5. Table Management
# Create a table from model schema
client.create_table(UserEvent)
# Delete and recreate (useful for schema changes)
client.recreate_table(UserEvent)
# Delete a table
client.delete_table(UserEvent)
6. Raw SQL Queries
results = client.query("""
SELECT user_id, COUNT(*) as event_count
FROM my_dataset.user_events
GROUP BY user_id
ORDER BY event_count DESC
LIMIT 10
""")
for row in results:
print(f"User {row['user_id']}: {row['event_count']} events")
Authentication
Credentials are loaded from environment variables (or .env file) in this priority:
-
Base64-encoded JSON (simplest for deployment):
BIGQUERY_CREDENTIALS=eyJ0eXBlIjoic2VydmljZV9hY2NvdW50Ii...
Generate with:
cat service-account.json | base64
-
Individual fields (useful for local development):
G_PROJECT_ID=your-project-id G_CLIENT_EMAIL=sa@your-project.iam.gserviceaccount.com G_PRIVATE_KEY="-----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY-----"
API Reference
BQBaseModel
Base class for defining BigQuery table schemas using Pydantic.
class MyTable(BQBaseModel):
# Define fields with type hints
name: str
count: int
price: float
is_active: bool
created_at: datetime
birth_date: date
tags: list[str] = []
description: Optional[str] = None
class Meta:
table_id = 'my_table'
table_description = 'Optional description'
Type mappings:
| Python Type | BigQuery Type | Mode |
|---|---|---|
str |
STRING | REQUIRED |
int |
INTEGER | REQUIRED |
float |
FLOAT | REQUIRED |
bool |
BOOL | REQUIRED |
datetime |
TIMESTAMP | REQUIRED |
date |
DATE | REQUIRED |
Enum |
STRING | REQUIRED |
Optional[T] |
T | NULLABLE |
list[T] |
T | REPEATED |
DatasetClient
Main client for BigQuery operations.
client = DatasetClient('my_dataset')
Methods:
| Method | Description |
|---|---|
table(Model) |
Get BQTable wrapper for CRUD operations |
view(Model) |
Get BQView wrapper for read-only operations |
query(sql) |
Execute raw SQL, returns list[dict] |
add_rows(*objs) |
Insert model instances (infers table from type) |
create_table(Model) |
Create table from model schema |
delete_table(Model) |
Delete a table |
recreate_table(Model) |
Drop and recreate table |
BQTable
Table wrapper with full CRUD support.
table = client.table(UserEvent)
Methods:
| Method | Description |
|---|---|
get_rows(fields=None, where=None, limit=None, as_objects=True) |
Fetch rows |
count_rows(where=None) |
Count rows |
add_rows(*objs, send_as_file=True) |
Insert rows |
delete_rows(where) |
Delete matching rows |
create() |
Create the table |
delete() |
Delete the table |
recreate() |
Drop and recreate |
BQView
View wrapper with read-only operations. Same query methods as BQTable.
Development
# Clone and install
git clone https://github.com/tutorcruncher/pydantic-bq.git
cd pydantic-bq
uv sync --all-extras
# Run tests (mocked)
uv run pytest tests/ -m "not e2e"
# Run E2E tests (requires credentials in .env)
uv run pytest tests/ -m e2e
# Lint and format
uv run ruff check .
uv run ruff format .
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantic_bq-0.1.5.tar.gz.
File metadata
- Download URL: pydantic_bq-0.1.5.tar.gz
- Upload date:
- Size: 19.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7cdcdf2fa38c98499d183c7dc435bf06cf7129212f3b5ab977ff66aea1793442
|
|
| MD5 |
4ebaff307b678a70777785ccdbe024dc
|
|
| BLAKE2b-256 |
e9d1e10da9c60fae7bbb3098844e3d282b98862bf706917e72097222e5a67486
|
Provenance
The following attestation bundles were made for pydantic_bq-0.1.5.tar.gz:
Publisher:
release.yml on tutorcruncher/pydantic-bq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_bq-0.1.5.tar.gz -
Subject digest:
7cdcdf2fa38c98499d183c7dc435bf06cf7129212f3b5ab977ff66aea1793442 - Sigstore transparency entry: 768932756
- Sigstore integration time:
-
Permalink:
tutorcruncher/pydantic-bq@545f90a5e70e506869d802b60d12d28335d3700f -
Branch / Tag:
refs/tags/0.1.5 - Owner: https://github.com/tutorcruncher
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@545f90a5e70e506869d802b60d12d28335d3700f -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantic_bq-0.1.5-py3-none-any.whl.
File metadata
- Download URL: pydantic_bq-0.1.5-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c64cbabc8e4c706e6aef5412f3789b9c2ad1938ec4e95949825de82df7d7b3c
|
|
| MD5 |
75d8e61c1bc60f3235ac2b929174eb02
|
|
| BLAKE2b-256 |
b2529e95a7f35b8e7940283e432a575f3ce4de151e0d53d35dfc3ac229a1cefd
|
Provenance
The following attestation bundles were made for pydantic_bq-0.1.5-py3-none-any.whl:
Publisher:
release.yml on tutorcruncher/pydantic-bq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_bq-0.1.5-py3-none-any.whl -
Subject digest:
5c64cbabc8e4c706e6aef5412f3789b9c2ad1938ec4e95949825de82df7d7b3c - Sigstore transparency entry: 768932759
- Sigstore integration time:
-
Permalink:
tutorcruncher/pydantic-bq@545f90a5e70e506869d802b60d12d28335d3700f -
Branch / Tag:
refs/tags/0.1.5 - Owner: https://github.com/tutorcruncher
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@545f90a5e70e506869d802b60d12d28335d3700f -
Trigger Event:
push
-
Statement type: