01
Locate the failing serialization boundary
Capture the exception type and stack location. A response encoder failing after rows were produced does not justify changing a query or granting more permissions. Separate query completion, result materialization, and outbound response serialization in the investigation.
Our constructed SDK Row first failed because Row itself was not JSON serializable. Converting it to dict moved the failure to a datetime field. A one-step conversion did not establish that every nested value was ready for JSON.
02
Inspect field types without exposing data
Check the types of the fields your response includes. BigQuery client values can require application-level decisions when exposed through a JSON API. Inspecting type names is usually sufficient to locate the conversion issue without logging private row contents.
The mapping below is a diagnostic for a row already in memory. It does not fetch rows or enumerate a table. Repeated records or arrays may contain nested values that also need deliberate conversion.
def field_types(row):
return {name: type(value).__name__ for name, value in row.items()}03
Define a precise response projection
For the tested order result, the API exposes a timezone-aware timestamp in ISO format and the exact decimal amount as a string. Those are explicit choices: consumers must know that amount is a decimal string, not a JSON number.
A different API may use another documented representation. Do not convert monetary values to float merely to make the encoder accept them. Avoid a blanket default=str that can hide unsupported fields and silently change the response schema.
def export_order_row(row):
return {
"order_id": row["order_id"],
"created_at": row["created_at"].isoformat(),
"amount": str(row["amount"]),
}04
Round-trip a representative value
Include the precision and timestamp cases that matter to consumers. Our fixture used Decimal("19.990000000") and an aware UTC datetime. The JSON round-trip preserved the intended decimal string and explicit UTC offset.
The following assertion checks the chosen response contract on a row supplied by the caller. Add separate handling and tests if nullable fields, repeated records, or other types are part of the actual API.
import json
def verify_order_response(row):
decoded = json.loads(json.dumps(export_order_row(row)))
assert decoded["amount"] == str(row["amount"])
assert decoded["created_at"] == row["created_at"].isoformat()
return decoded05
Check the final HTTP response separately
Run the application endpoint with an approved representative fixture and confirm its status, content type, and response values. A converter passing in isolation does not establish that the endpoint uses it or that another serialization layer leaves the shape intact.
The local SDK Row test makes no claim about SQL correctness, query costs, result paging, or live permissions. Keep those checks tied to their own evidence instead of conflating a response-format error with a database execution failure.
Sınırları bil
Reproduced with google-cloud-bigquery 3.46.2 using an actual SDK Row containing a timezone-aware datetime and Decimal. Direct JSON encoding failed; an explicit projection round-tripped with the intended strings. No BigQuery query, customer data, or export job was executed.
Kaynaklar ve ileri okuma
CoreTrailKit tarafından hazırlanan teknik yayın.
Bütün yazıları keşfet