Repository navigation
fix(websocket): Preset fallback build 7.1.3.1 — timestamp precision and pre-ping recovery - #1
Conversation
* Fix bare SQLAlchemy dialect entry point Load the default websocket dialect class directly so entry-point consumers do not receive a legacy module. Cover installed discovery, Superset's dialect shape, and both Exasol engine URL forms. * Strengthen dialect entry point regression checks * Reference entry point issue in changelog
* Prepare release 7.1.3
Qualification results — all run on this exact head
|
| Suite | Result |
|---|---|
test/unit |
116 passed |
test/integration/sqlalchemy (dialect compliance) |
746 passed, 526 skipped, 33 xfailed, 0 failed |
test/integration/exasol |
113 passed, 2 failed (see below) |
test/integration/regression |
4 passed |
test/integration/exasol/test_websocket_recovery.py |
12 passed |
Causality control. With sqlalchemy_exasol/websocket.py reverted to unmodified upstream 7.1.3 and nothing else changed, the same 12 cases give 10 failed / 2 passed. With the fix: 12 passed. The regressions therefore track exactly the two defects this branch fixes.
The 2 test/integration/exasol failures are pre-existing, not regressions. Controlled the same way on unmodified 7.1.3: test_udf.py::Udf::test_udf and test_large_metadata.py::test_reflect_table_object fail there too (the control run actually failed one more test, test_reflect_metadata_object). test_udf fails because Nano cannot create PYTHON3 SCALAR SCRIPT UDFs; test_large_metadata is size/timing-sensitive on this small server. Neither touches the changed code paths.
Artifacts built (local only — nothing published)
sqlalchemy_exasol-7.1.3.1.tar.gz sha256 825cf9a4def84f59d2b7d619433ed6b66afbebb9ccd3a5212c5b0ea46c0faec8
sqlalchemy_exasol-7.1.3.1-py3-none-any.whl sha256 f841754a1d775576acc39cb8137dbf9b2f7214a3a71c8547030e858eebbc2602
Verified: poetry build succeeds; the wheel and the sdist both install into a clean venv reporting 7.1.3.1; the installed dialect carries the is_disconnect override; and uv pip compile resolves a direct-URL requirement for it and emits the pin in the same form Shell already uses.
Smallest safe publication path (design only — do not execute yet)
the internal package index is a public-read S3 bucket (preset-pypi) serving flat per-project prefixes — PyHive/, ai-assist/, firebolt-sqlalchemy/. Shell consumes it as direct sdist URLs, e.g. setup.py already carries pyhive[...]@s3://preset-pypi/PyHive/pyhive-0.7.0.1.tar.gz. There is no sqlalchemy-exasol/ prefix today, so the key below is free.
- Build reproducibly from this head —
poetry build— and match the sha256 values above. - Upload one object to
s3://preset-pypi/sqlalchemy-exasol/sqlalchemy_exasol-7.1.3.1.tar.gz(optionally the wheel alongside). This must be done by someone who already holds bucket write access, using their existing SSO/role credentials, or by a CI job assuming an org OIDC role — the same trusted-publishing shape as Shell'sgithub-actions-bedrock-role. No long-lived token should be pasted into a shell, a workflow file, or this thread; nothing in this branch reads or needs a credential. - Consume from Shell in a separate PR: replace
setup.py:228"sqlalchemy-exasol==7.1.3"with the direct URL and relock with the documenteduv pip compilecommand.
+ must be percent-encoded in the consuming URL:
s3://preset-pypi/PyHive/pyhive-0.7.0.2%2Bpr.4.c26b81d.tar.gz → 200
s3://preset-pypi/PyHive/pyhive-0.7.0.2+pr.4.c26b81d.tar.gz → 404
So the Shell pin must read …/sqlalchemy-exasol/sqlalchemy_exasol-7.1.3%2Bpreset.1.tar.gz. I confirmed pip install from a %2B URL resolves and reports 7.1.3.1. Local +pr.N.<sha> versions are already established practice in this bucket, so the form is not novel — but if an owner would rather avoid the encoding entirely, the drop-in alternative is 7.1.3.1, matching the pyhive-0.7.0.1 precedent Shell consumes today; it sorts identically (above 7.1.3, below 7.1.4). Say which you prefer before anything is uploaded.
Gates still open
- Fork CI is not running. Only the
Dependency Graphworkflow is registered onpreset-io/sqlalchemy-exasol, so this PR reports no checks even though the upstream workflow files are present. GitHub disables workflows on forks until a repo admin opens Actions → “I understand my workflows, go ahead and enable them”; this cannot be done through the REST API (actions/permissionsalready reportsenabled: true). All qualification above is therefore local, not CI-attested. - Owner confirms the bucket key, the version form, and who performs the upload.
- Separate Shell PR for the pin + relock; Shell #5084 stays test-only and untouched.
- Upstream #808 stays open — it remains the preferred outcome. Nothing here is tagged, released or merged, and Fix websocket timestamp precision and pre-ping disconnect recovery exasol/sqlalchemy-exasol#808 will not be closed.
Updated 2026-09-16. Version decision is now 7.1.3.1 (four-component, matching the PyHive/Drill convention), so the %2B encoding caveat above no longer applies to this artifact — the Shell pin is a plain URL:
sqlalchemy-exasol @ s3://preset-pypi/sqlalchemy-exasol/sqlalchemy_exasol-7.1.3.1.tar.gz
Checksums and the head SHA in this comment have been updated to the rebuilt 7.1.3.1 artifacts. The reviewed fix tree is unchanged: git diff --quiet 44f4792 92039cf6 still reports the parent tree byte-identical to the upstream exasol#808 head; only the tip commit carries the version and provenance note.
Rebuild of upstream 7.1.3 carrying only the reviewed websocket timestamp-precision and pre-ping disconnect fixes from exasol#808. Uses Preset's existing four-component convention for rebuilt third-party packages (cf. pyhive-0.7.0.1), which keeps the artifact filename free of a '+' and therefore free of URL percent-encoding on the internal index. Upstream has only ever released three-component versions; 7.1.3.1 sorts above 7.1.3 and below 7.1.4, so an upstream release supersedes it automatically. Internal index only; never published to public PyPI. Refs SC-120359.
49227ff to
8af5fb7
Compare
CI is now live on this fork, and it is green apart from one external-credential gateExact head: 63 jobs succeeded, 1 failed, 1 blocked behind it. This is materially stronger evidence than upstream exasol#808 has ever been able to produce, because exasol#808's slow-test and extension gates are stuck awaiting maintainer approval. Here they ran:
The one failure —
|
| Workflow | State |
|---|---|
| Build & Publish | disabled_manually |
| CD | disabled_manually |
| Check Release Tag | disabled_manually |
| Publish Documentation | disabled_manually |
| PR-Merge | disabled_manually |
| Dependency Update / Periodic-Validation | disabled_fork (default) |
| CI, Checks, Fast-Tests, Merge-Gate, Slow-Checks, Verify examples, Build Matrix | active |
The fork's master remains untouched: it is protected (1 approving review, enforce_admins: true) and I did not alter that protection, which is why this PR is based on preset/upstream-7.1.3.
Nothing published, tagged, merged or released. Upstream exasol#808 is untouched and stays open.
The upstream report workflow uploads coverage to Exasol's own SonarQube organization with a SONAR_TOKEN only exasol/sqlalchemy-exasol holds. A fork cannot authenticate there and must not be given that secret, so the job fails on this fork for reasons unrelated to the code under review. Guard the upload step with github.repository != 'preset-io/sqlalchemy-exasol' so behaviour is unchanged for exasol/sqlalchemy-exasol and for every other fork, and add GitHub CodeQL (Python, security-and-quality) as the replacement static-analysis gate on this fork only. The guard is expressed through the exasol-toolbox's supported .workflow-patcher.yml mechanism rather than by hand-editing a generated workflow, so 'nox -s workflow:check -- all' still passes. The CodeQL action is hash-pinned per the repository's zizmor unpinned-uses policy; 'nox -s workflow:audit' reports no findings. No lint, typing, security or test job is removed, skipped or relaxed. Publishing and release workflows remain disabled on this fork. Refs SC-120359.
Preset-fork CI adaptation — CI is now terminal green at
|
Adversarial code reviewSmaller, high-quality PR with strong tests. The findings center on the disconnect-detection contract: 1.
|
Purpose
Release-blocker fallback for SC-120359. Upstream exasol/sqlalchemy-exasol#808 stays open and is still the preferred path; this PR exists so Preset is not blocked if upstream review/release does not land in time.
Production Shell pins
sqlalchemy-exasol==7.1.3, which carries two defects reproduced against Exasol Nano:websocket.DateTime.result_processorparses throughtime.strptime/mktime, losing fractional seconds and reinterpreting naive wall time in the client's timezone.is_disconnect() == False, so SQLAlchemy'spool_pre_pingcannot recognize a dead pooled connection and the first checkout after a killed session fails.Exact provenance
The first two commits are
git cherry-picked from the reviewed upstream head, with original authorship and author dates preserved:06d6a142f88949e721bdcbd45f544d9e2b463c66603b94744f479292039cf65b1160293e04567cf403ab56064d0b7fVerified:
git diff --quiet 44f4792 92039cf6— the tree at44f4792is byte-identical to the reviewed upstream head. Base is upstream'sfb2675b4(“Prepare release 7.1.3”, exasol#804), pushed unmodified topreset/upstream-7.1.3because this fork'smasteris protected and 30+ commits stale; that keeps this diff to exactly the fix plus the version marker.The third commit
49227ffis the only Preset-owned change: the internal artifact version and a provenance note.Version choice
7.1.3.1— a four-component PEP 440 release version, following Preset's existing convention for rebuilt third-party packages (pyhive-0.7.0.1, consumed by Shell today). Verified withpackaging: it sorts above7.1.3and below7.1.4, so any future upstream release supersedes it automatically in resolution. Upstream has only ever published three-component versions (7.1.0–7.1.3,6.x,5.x), so the fourth component cannot collide.This replaces the earlier
7.1.3.1proposal. A PEP 440 local segment is collision-proof, but the internal index requires the+to be percent-encoded in the consuming URL — verified against the live host,…pyhive-0.7.0.2%2Bpr.4.c26b81d.tar.gzreturns 200 while the literal+form returns 404.7.1.3.1keeps the artifact filename and the Shell pin free of any encoding.Internal index only; never published to public PyPI.
Scope
No workflow, CI, packaging-backend or dependency changes. No new runtime dependency. Nothing is published, tagged or released by this PR.
Gates before any publication
Supersede and close this in favour of the upstream release as soon as exasol#808 ships.