034: fix double JSON serialization in AsyncAPIClient.request
Root cause: AsyncAPIClient.request() passes its parameter directly
to httpx.AsyncClient.request(json=data). When callers pass a pre-serialized
JSON string (data=json.dumps(dict)), httpx re-encodes it via json.dumps(),
resulting in a double-encoded JSON string body instead of a JSON object.
This caused ALL POST/PUT requests with string data to fail — Superset received
a JSON string instead of a JSON object, returning GENERIC_BACKEND_ERROR
('dictionary update sequence element #0 has length 1; 2 is required').
Fix: if data is a string, pass it via httpx parameter (raw body);
if it's a dict/list, pass via for automatic encoding.
Affected callers (6 files) now correctly send JSON objects:
- preview_executor.py: chart data requests
- superset_executor.py
- _run_source.py
- _datasets.py: update_dataset
- _datasets_preview.py: compile_dataset_preview
- _dashboards_write.py
Also simplified preview_executor.fetch_sample_rows back to single-strategy
(chart data API only) since the root cause is now fixed.
This commit is contained in:
@@ -37,7 +37,7 @@ class PreviewExecutor:
|
||||
|
||||
# region fetch_sample_rows [TYPE Function]
|
||||
# @PURPOSE: Fetch sample rows from Superset dataset for preview.
|
||||
# @SIDE_EFFECT Calls Superset chart data endpoint.
|
||||
# @SIDE_EFFECT Calls Superset chart data API.
|
||||
async def fetch_sample_rows(
|
||||
self,
|
||||
job: TranslationJob,
|
||||
@@ -60,13 +60,20 @@ class PreviewExecutor:
|
||||
dataset_id=int(job.source_datasource_id), dataset_record=dataset_detail,
|
||||
template_params={}, effective_filters=[],
|
||||
)
|
||||
|
||||
# Build column list from dataset schema for explicit column projection
|
||||
column_names = [
|
||||
col["name"] for col in dataset_detail.get("columns", [])
|
||||
if col.get("name") and col.get("is_active", True)
|
||||
]
|
||||
|
||||
queries = query_context.get("queries", [])
|
||||
if queries:
|
||||
queries[0]["row_limit"] = sample_size
|
||||
queries[0].pop("result_type", None)
|
||||
queries[0].pop("columns", None)
|
||||
queries[0]["columns"] = column_names or []
|
||||
queries[0]["metrics"] = []
|
||||
query_context["result_type"] = "samples"
|
||||
queries[0].pop("result_type", None)
|
||||
query_context["result_type"] = "query"
|
||||
form_data = query_context.get("form_data", {})
|
||||
form_data.pop("query_mode", None)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user