villebro opened a new pull request, #43410: URL: https://github.com/apache/superset/pull/43410
> **Part of the [GAQ→GTF epic](https://github.com/apache/superset/pull/43407)** — this is **PR 2 (Canonical `QueryObject` serialization)**, targeting the `gaq-to-gtf` feature branch. ### SUMMARY Adds a canonical, JSON-safe, self-contained serialization for a **single chart-data query** — the atomic unit a later PR (PR 3) will run as its own async GTF task. Today the async path serializes the *entire* query context (the request dict misleadingly named `form_data`); PR 3 will instead fan out one task per `QueryObject`, and each task needs to reconstruct exactly its query so it caches under the same `query_cache_key` as the synchronous path. This PR provides that primitive (with tests); PR 3 consumes it. **API** (`superset/common/query_serialization.py`): - `serialize_query(query_context, query_index) -> SerializedQuery` — a JSON-safe dict of the **raw** query (from `QueryContext.cache_values["queries"]`) plus the context-level inputs needed to rebuild it: `datasource`, `form_data`, `result_type`, `result_format`, `force`, `custom_cache_timeout`. - `load_serialized_query(payload) -> QueryContext` — rebuilds a **single-query** `QueryContext` via `QueryContextFactory` (the same path that produced the original), so `query_cache_key` matches. **Why the raw query, not `QueryObject.to_dict()`.** Reconstructing from `to_dict()` would change the cache key: `to_dict()` emits `from_dttm`/`to_dttm` as raw datetimes, uses the key `filter` where the factory expects `filters`, and omits `time_range`/`datasource`/`result_type`. Serializing the raw schema-shaped query and rebuilding through the factory reuses the exact key-producing path (the same pattern `Slice.query_context` already relies on), giving a provably identical `query_cache_key`. **`force`/`custom_cache_timeout` survival.** These live on `QueryContext`, not `QueryObject`, so a per-query payload must carry them explicitly — they're serialized and restored, and the integration test asserts it. ### BEFORE / AFTER No behavior change to the live async flow in this PR — it adds a foundation primitive. The misleading `form_data` rename and the duplicate `_create_query_context_from_form` dedup are intentionally deferred to **PR 3**, which rewrites `tasks/async_queries.py` and replaces `create_async_job_command.py` (doing the rename here would be throwaway). ### TESTING INSTRUCTIONS - Unit (`tests/unit_tests/common/test_query_serialization.py`, green locally): payload extraction reads the raw query + context params; payload is JSON round-trippable; `load_serialized_query` reconstructs via `QueryContextFactory` with `result_type`/`result_format` back as enums. - Integration (`tests/integration_tests/query_context_tests.py::test_serialize_query_round_trip_preserves_cache_key`): builds a real `birth_names` query context, serializes + reloads query 0, and asserts the reconstructed `query_cache_key` equals the original and that `force`/`custom_cache_timeout`/`result_type`/`result_format` survive. ### ADDITIONAL INFORMATION - [ ] Has associated issue - [ ] Changes UI - [ ] Includes DB Migration - [x] Introduces new feature or API (`serialize_query` / `load_serialized_query`) - [ ] Removes existing feature or API _Note: the whole-project frontend type-check has pre-existing failures unrelated to this change._ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
