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]

Reply via email to