Repository navigation
Add Cloudflare Hyperdrive support for Python Workers - #28
Merged
Merged
Conversation
CollierKing
force-pushed
the
feature/hyperdrive-support
branch
from
September 19, 2026 04:06
1b0b110 to
6a7f942
Compare
Adds create_engine_from_hyperdrive() and hyperdrive_connection() for using SQLAlchemy against a PostgreSQL database through a Hyperdrive binding inside a Python Worker. No dialect is involved: Hyperdrive speaks the real wire protocol, so SQLAlchemy's own postgresql+pg8000 does the work and this module supplies only the binding-to-engine glue. Engines use NullPool, since a Worker cannot reuse sockets across requests and Hyperdrive pools server-side. hyperdrive_connection() holds a per-event-loop asyncio lock, because the Workers socket layer does not tolerate concurrent synchronous driver I/O. The driver is chosen from the binding's scheme and can be overridden. Of the five drivers Cloudflare documents, only pg8000 and pymysql can back a SQLAlchemy engine. psycopg needs libpq, which the Workers Pyodide build lacks, and asyncpg and aiomysql are async-only while SQLAlchemy's async engine requires greenlet. Both usable drivers need TLS explicitly disabled, spelled differently for each, since Hyperdrive terminates TLS itself. PostgreSQL is the supported path and is covered by Worker integration tests. MySQL is best effort: verified by hand against MySQL 8, but with no automated coverage. The two drivers ship as separate extras so a PostgreSQL deployment does not carry a MySQL driver, and a missing driver reports which extra provides it. Also derives the package version from __version__, which had drifted to 0.3.1 while the package shipped 0.3.11, and releases 0.4.0.
CollierKing
force-pushed
the
feature/hyperdrive-support
branch
from
September 19, 2026 04:18
6a7f942 to
0a7e005
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
create_engine_from_hyperdrive()andhyperdrive_connection()for using SQLAlchemy against PostgreSQL through a Cloudflare Hyperdrive binding inside a Python Workerpostgresql+pg8000does the work and this package supplies only the binding-to-engine glueNullPool, since a Worker cannot reuse sockets across requests and Hyperdrive pools server-sidehyperdrive_connection()holds a per-event-loopasyncio.Lock, because the Workers socket layer does not tolerate concurrent synchronous driver I/Oscheme, falling back toconnectionString, and can be overridden withdriver=[hyperdrive]extra and anexamples/workers-hyperdrive/example WorkerDriver support
Cloudflare documents five drivers for Python Workers. Only two can back a SQLAlchemy engine, verified by running each from inside a Worker:
pg8000pymysqlpsycopgasyncpgaiomysqlOnly synchronous SQLAlchemy works.
asyncpgandaiomysqlrun fine in Workers on their own, but driving them from SQLAlchemy requirescreate_async_engine()and therefore greenlet, which Workers lack — so the two drivers Cloudflare recommends are precisely the two that cannot be used here.Both supported drivers need TLS explicitly disabled, spelled differently for each, since Hyperdrive terminates TLS itself.
Notes for reviewers
wrangler devalways connects to the Postgres named byCLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE, and"remote": trueis not valid on a hyperdrive binding. Integration tests skip unless that variable is set.ADMIN_TOKENwhen one is set, because a deployed Worker is publicly reachable.__version__had drifted to0.3.1while the package shipped0.3.11. The version is now derived from__version__via hatchling, with a test asserting the two agree.Testing
ruff check,ruff format --diff,codespell,mypy src/,pre-commit --all-filesanduv buildall clean