danielalyoshin opened a new pull request, #44505:
URL: https://github.com/apache/superset/pull/44505

   <!---
   Please write the PR title following the conventions at 
https://www.conventionalcommits.org/en/v1.0.0/
   Example:
   fix(dashboard): load charts correctly
   -->
   
   ### SUMMARY
   <!--- Describe the change below, including rationale and design decisions -->
   
   The `d1` extra is one of the connector extras still held back from 
SQLAlchemy 2. `UPDATING.md` lists it under "the upstream dialect package has no 
SQLAlchemy 2.0 support yet at all", and `superset/db_engine_specs/d1.py` 
carries a `known_incompatibilities` entry whose `tracking_url` points at our 
repo. This PR lifts that block. I am one of the maintainers of the 
`sqlalchemy-cf-d1` packages.
   
   What changed on our side:
   
   * `sqlalchemy-d1` 0.2.0 supports SQLAlchemy 2. It keeps the `d1://` scheme 
and is a thin layer over the community dialect 
[`sqlalchemy-cloudflare-d1`](https://github.com/CollierKing/sqlalchemy-cloudflare-d1).
 It is on PyPI: [sqlalchemy-d1 
0.2.0](https://pypi.org/project/sqlalchemy-d1/0.2.0/).
   * `superset-engine-d1` and `dbapi-d1` are retired. The engine spec of record 
is the one in this repo. It has taken priority over the external one for 
`d1://` since 6.1.0. `sqlalchemy-d1` 0.2.0 gets its DBAPI from 
`sqlalchemy-cloudflare-d1`, so nothing needs `dbapi-d1` any more.
   
   What this PR changes:
   
   * `pyproject.toml`: the `d1` extra installs `sqlalchemy-d1>=0.2.0, <1` only.
   * `superset/db_engine_specs/d1.py`:
     * `pypi_packages` names `sqlalchemy-d1`, and the `known_incompatibilities` 
entry is removed.
     * `install_instructions` is `pip install "apache-superset[d1]"` with a 
`version_requirements` note, as #44285 did for Presto. A bare `pip install 
sqlalchemy-d1` would call the requirement met on an environment that still has 
0.1.0.
     * `allows_sql_comments = False`. The DBAPI in `sqlalchemy-cloudflare-d1` 
only reports column names when the statement text starts with `SELECT`, 
`PRAGMA` or `WITH`, so a query with a leading comment came back as rows without 
a cursor description and SQL Lab failed on it. With the flag off, Superset 
strips the comment first.
   * `UPDATING.md`: `d1` is taken off the list of blocked extras, and a note 
tells existing installs to uninstall the two retired packages.
   * `docs/src/data/databases.json`: the matching lines for D1, edited by hand 
as #42125 and #44285 did.
   * `tests/unit_tests/db_engine_specs/test_d1.py`: new. Covers the comment 
stripping, the metadata, and that the type names the dialect reports 
(`DATETIME`, `TIMESTAMP`, `DATE`, `TIME`, `BOOLEAN`) map to temporal and 
boolean columns.
   
   D1 keeps internal `_cf_*` tables (for example `_cf_KV`) in every database. 
The `sqlalchemy-d1` dialect hides them, so the spec does not need to.
   
   Existing `d1://` connections keep working. The connection string does not 
change.
   
   **Request: please consider this for 7.0.** The `7.0` branch is the first on 
SQLAlchemy 2 and still lists all three packages in the `d1` extra. 
`superset-engine-d1` 0.1.0 and `dbapi-d1` 0.1.0 both require Python below 3.12, 
so without this change `pip install apache-superset[d1]` on 7.0 only works on 
Python 3.11. The change is small and cherry-picks onto `7.0` without conflicts 
(checked against `c636115d40`). If a committer agrees, a `v7.0` label would be 
appreciated.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   <!--- Skip this if not applicable -->
   
   **1. Test connection succeeds for a `d1://` database (connection string 
blurred).**
   
   <img width="1440" height="757" alt="01-test-connection" 
src="https://github.com/user-attachments/assets/ef6161d4-031e-4e0e-873a-6028f613c32b";
 />
   
   **2. SQL Lab lists the tables and the view but not `_cf_KV`, and a 
`DATETIME` column holding a number, an empty string and `09/21/2026` still 
previews.**
   
   <img width="1440" height="757" alt="02-sql-lab-table-list-and-messy-dates" 
src="https://github.com/user-attachments/assets/99514f67-ff6b-4baa-91f1-154cb679f1b8";
 />
   
   **3. A dataset from a D1 table marks its `DATETIME` and `DATE` columns 
temporal on its own.**
   
   <img width="1440" height="806" alt="03-dataset-temporal-columns" 
src="https://github.com/user-attachments/assets/be3e7d7e-266f-4e58-9bfb-249e913b12b9";
 />
   
   **4. A line chart with a daily time grain.**
   
   <img width="1440" height="806" alt="04-daily-line-chart" 
src="https://github.com/user-attachments/assets/e8703d26-8dc9-4542-9ad3-1f2a120ce3d1";
 />
   
   ### TESTING INSTRUCTIONS
   <!--- Required! What steps can be taken to manually verify the changes? -->
   
   Unit tests:
   
   ```bash
   pytest tests/unit_tests/db_engine_specs/test_d1.py
   ```
   
   By hand, against a real D1 database:
   
   1. `pip install "apache-superset[d1]"`, or `pip install 
"sqlalchemy-d1>=0.2.0"` into an existing Superset environment. Do not install 
`superset-engine-d1` or `dbapi-d1`.
   2. Add a database with 
`d1://{cloudflare_account_id}:{cloudflare_api_token}@{cloudflare_d1_database_id}`.
 **Test connection** succeeds.
   3. In SQL Lab, `SELECT * FROM <table> WHERE 1=0` returns the column headers 
and no rows.
   4. Create a dataset from a table with `DATETIME` and `DATE` columns. Both 
are marked temporal. A line chart with a daily time grain renders.
   5. `_cf_KV` is not in the table list.
   6. In SQL Lab, a query that starts with a `-- comment` line runs and shows 
its columns.
   
   Results. I ran the full list on the final state of this branch on 
2026-09-21, in the `docker-compose-light.yml` stack (Python 3.11.14, SQLAlchemy 
2.0.52), with `sqlalchemy-d1` 0.2.0 and `sqlalchemy-cloudflare-d1` 0.4.0 
installed through `docker/requirements-local.txt`, against a real D1 database. 
`superset-engine-d1` and `dbapi-d1` were not installed.
   
   | Check | Result |
   |-------|--------|
   | `get_engine_spec("d1")` returns `CloudflareD1EngineSpec`, no spec load 
warnings in the log | pass |
   | Cloudflare D1 is in the database list, **Test connection** succeeds | pass 
|
   | SQL Lab: `SELECT 1` | pass |
   | SQL Lab: a query with zero rows returns its column names and no error | 
pass |
   | SQL Lab: a query that starts with a `--` or a `/* */` comment runs and 
returns its columns | pass |
   | SQL Lab: a bad query gives a readable error | pass |
   | The table list does not show `_cf_KV` | pass |
   | A table whose `DATETIME` column holds a number, an empty string and 
`09/21/2026` still previews | pass |
   | A dataset from a table marks its `DATETIME` and `DATE` columns temporal on 
its own | pass |
   | A line chart with a daily time grain renders, also with a time range 
filter | pass |
   | A view is listed and works as a dataset | pass |
   | A dashboard with a D1 chart loads and refreshes | pass |
   
   ### ADDITIONAL INFORMATION
   <!--- Check any relevant boxes with "x" -->
   <!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
   
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
     - [ ] Migration is atomic, supports rollback & is backwards-compatible
     - [ ] Confirm DB migration upgrade and downgrade tested
     - [ ] Runtime estimates and downtime expectations provided
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   


-- 
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