pyro-mysql
A high-performance MySQL driver for Python, backed by Rust.
Usage
0. Import
# Async
from pyro_mysql.async_ import Conn
from pyro_mysql import AsyncConn
# Sync
from pyro_mysql.sync import Conn
from pyro_mysql import SyncConn
1. Connection
from pyro_mysql.async_ import Conn
from pyro_mysql import Opts
async def example():
conn1 = await Conn.new(f"mysql://{USER}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}")
conn2 = await Conn.new(
Opts(f"mysql://{USER}:{PASSWORD}@localhost")
.tcp_nodelay(False)
)
conn3 = await Conn.new(
Opts()
.socket("../unix.socket")
.user("username")
.db("db")
)
2. Query Execution
SyncConn and AsyncConn provides the following 8 methods (SyncConn doesn't return Awaitable):
# Text Protocols - supports multiple statements concatenated with ';' but accepts no argument
def query(self, query: str, *, as_dict: bool = False) -> Awaitable[list[tuple] | list[dict]]: ...
def query_first(self, query: str, *, as_dict: bool = False) -> Awaitable[tuple | dict | None]: ...
def query_drop(self, query: str) -> Awaitable[None]: ...
# Binary Protocols - supports arguments but no multiple statement
def exec(self, query: str, params: Params = None, *, as_dict: bool = False) -> Awaitable[list[tuple] | list[dict]]: ...
def exec_first(self, query: str, params: Params = None, *, as_dict: bool = False) -> Awaitable[tuple | dict | None]: ...
def exec_drop(self, query: str, params: Params = None) -> Awaitable[None]: ...
def exec_batch(self, query: str, params: Sequence[Params] = []) -> Awaitable[None]: ...
def exec_bulk_insert_or_update(self, query: str, params: Sequence[Params] = [], *, as_dict: bool = False) -> Awaitable[list[tuple] | list[dict]]: ...
# Examples
rows = await conn.exec("SELECT * FROM my_table WHERE a=? AND b=?", (a, b)) # returns list of tuples
rows_as_dicts = await conn.exec("SELECT * FROM my_table WHERE a=? AND b=?", (a, b), as_dict=True) # returns list of dicts
await conn.exec_batch("SELECT * FROM my_table WHERE a=? AND b=?", [(a1, b1), (a2, b2)])
Awaitable is a coroutine or PyroFuture, which is a Future-like object that tracks a task in the Rust thread. If the returned object is dropped before completion or cancellation, the corresponding task in the Rust thread is cancelled as well.
3. Transaction
# async API
async with conn.start_transaction() as tx:
await conn.exec('INSERT ..')
await conn.exec('INSERT ..')
await tx.commit()
# sync API
with conn.start_transaction() as tx:
conn.exec('INSERT ..')
conn.exec('INSERT ..')
tx.rollback()
DataType Mapping
Python -> MySQL
| Python Type | MySQL Binary Protocol Encoding |
|---|---|
None |
NULL |
bool |
Int64 |
int |
Int64 |
float |
Double(Float64) |
str | bytes | bytearray |
Bytes |
tuple | list | set | frozenset | dict |
json-encoded string as Bytes |
datetime.datetime |
Date(year, month, day, hour, minute, second, microsecond) |
datetime.date |
Date(year, month, day, 0, 0, 0, 0) |
datetime.time |
Time(false, 0, hour, minute, second, microsecond) |
datetime.timedelta |
Time(is_negative, days, hours, minutes, seconds, microseconds) |
time.struct_time |
Date(year, month, day, hour, minute, second, 0) |
decimal.Decimal |
Bytes(str(Decimal)) |
uuid.UUID |
Bytes(UUID.hex) |
MySQL -> Python
| MySQL Column | Python |
|---|---|
NULL |
None |
INT / TINYINT / SMALLINT / MEDIUMINT / BIGINT / YEAR |
int |
FLOAT / DOUBLE |
float |
DECIMAL / NUMERIC |
decimal.Decimal |
DATE |
datetime.date or None (0000-00-00) |
DATETIME / TIMESTAMP |
datetime.datetime or None (0000-00-00 00:00:00) |
TIME |
datetime.timedelta |
CHAR / VARCHAR / TEXT / TINYTEXT / MEDIUMTEXT / LONGTEXT |
str |
BINARY / VARBINARY / BLOB / TINYBLOB / MEDIUMBLOB / LONGBLOB |
bytes |
JSON |
str or the result of json.loads() |
ENUM / SET |
str |
BIT |
bytes |
GEOMETRY |
bytes |
Logging
pyro-mysql sends the Rust logs to the Python logging system, which can be configured with logging.getLogger("pyro_mysql").
# Queries are logged with the DEBUG level
logging.getLogger("pyro_mysql").setLevel(logging.DEBUG)
PEP-249, sqlalchemy
pyro_mysql.dbapi implements PEP-249.
This only exists for compatibility with ORM libraries.
The primary API set (pyro_mysql.sync, pyro_mysql.async_) is simpler and faster.
pyro_mysql.dbapi
# classes
├─Connection
├─Cursor
# exceptions
├─Warning
├─Error
├─IntegrityError
├─..
In sqlalchemy, the following dialects are supported.
mysql+pyro_mysql://(sync)mariadb+pyro_mysql://(sync)mysql+pyro_mysql_async://(async)mariadb+pyro_mysql_async://(async)
Connection options can be configured using the Opts builder class. See pyro_mysql.Opts for available options.
from sqlalchemy import create_engine, text
engine = create_engine("mysql+pyro_mysql://test:1234@localhost/test")
conn = engine.connect()
cursor_result = conn.execute(text("SHOW TABLES"))
for row in cursor_result:
print(row)
('information_schema',)
('mysql',)
('performance_schema',)
('sys',)
('test',)
To run sqlalchemy tests on pyro_mysql, use this command in the sqlalchemy repo:
pytest -p pyro_mysql.testing.sqlalchemy_pytest_plugin --dburi=mariadb+pyro_mysql://test:1234@localhost/test -v t
sqlalchemy_pytest_plugin is required to skip incompatible tests.
API Overview
- pyro_mysql
- pyro_mysql,sync
- pyro_mysql.async_
- pyro_mysql.dbapi
- pyro_mysql.dbapi_async
- pyro_mysql.error
There is no auto-generated API Reference. *.pyi files are manually synced.
.
└── pyro_mysql/
├── (common classes)/
│ ├── Opts
│ ├── BufferPool
│ ├── IsolationLevel
│ ├── CapabilityFlags
│ └── PyroFuture
├── sync/
│ ├── Conn
│ └── Transaction
├── async_/
│ ├── Conn
│ └── Transaction
├── dbapi/
│ ├── connect()
│ ├── Connection
│ ├── Cursor
│ └── (exceptions)
│ ├── Warning
│ ├── Error
│ ├── InterfaceError
│ ├── DatabaseError
│ ├── DataError
│ ├── OperationalError
│ ├── IntegrityError
│ ├── InternalError
│ ├── ProgrammingError
│ └── NotSupportedError
├── dbapi_async/
│ ├── connect()
│ ├── Connection
│ ├── Cursor
│ └── (exceptions)
│ ├── Warning
│ ├── Error
│ ├── InterfaceError
│ ├── DatabaseError
│ ├── DataError
│ ├── OperationalError
│ ├── IntegrityError
│ ├── InternalError
│ ├── ProgrammingError
│ └── NotSupportedError
└── (aliases)/
├── SyncConn
├── SyncTransaction
├── AsyncConn
├── AsyncTransaction
└── Opts
Perf Notes
- Prefer MariaDB to MySQL
- Prefer UnixSocket to TCP
- Use BufferPool to reuse allocations between connections
- Use Conn.exec_bulk_insert_or_update to group 2~1000 INSERTTs or UPDATEEs
- The async API is fast but still far from optimal due to GIL. Wait for Python 3.14 + mature free-threaded build for faster asyncio performance
- The sync API is optimized for single-thread. The library does not actively release the GIL during operations. When free-threaded python gets mature, the optimal API will be reconsidered.
Metadata
Release files for pyro-mysql 0.2.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| pyro_mysql-0.2.16-cp310-abi3-win_arm64.whl | CPython 3.10 | abi3 | Windows ARM64 | Details |
| pyro_mysql-0.2.16-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| pyro_mysql-0.2.16-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
| pyro_mysql-0.2.16-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 11.2 MB
Release files / pyro_mysql-0.2.16-cp310-abi3-win_arm64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-win_arm64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.10 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
642d92156109ff47b7a947412ed1aa34bc663ce448e34ddcf06dc7801cb22bbc
|
|
BLAKE2b-256 checksum How to use checksums |
fd6e4531bab2f668772cfaa8d35c9590527223e987ba36eac6e932fe9df25a22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logRelease files / pyro_mysql-0.2.16-cp310-abi3-win_amd64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
dc0341ad6a010655f567a100a16e6132187891b023d4408037695c4344a1cee6
|
|
BLAKE2b-256 checksum How to use checksums |
cbab6316b19b580ca270039a4fe513ce430d6653ee3181038274d4562dcb3e79
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logRelease files / pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 3.5 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
7bd1838c44fa9e726ec87d315e53ed5c9d3b171adef213440d61b0e2ec7a7376
|
|
BLAKE2b-256 checksum How to use checksums |
03404fb183e1b5fe7c6a24f30d27235aab825dbc00de829386789a25559b81d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logRelease files / pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 3.2 MB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
c362316080c5c5f9bd72f3295f97438b2f2336c5b3250fc4b31061e1cce105c9
|
|
BLAKE2b-256 checksum How to use checksums |
6dc70703825ded1902dc7054b224ed5558766bff2a845a14eb128f2c9e8c3ef9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logRelease files / pyro_mysql-0.2.16-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.1 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
68f62d43b0d55555a78d7e3d59136eadb323eafc17c1d6490d602a7d9d85d139
|
|
BLAKE2b-256 checksum How to use checksums |
3a5b31ac78c6c7c768a84270540c04c9654226aa9cf03961644c4d7616d21faf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logRelease files / pyro_mysql-0.2.16-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | pyro_mysql-0.2.16-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
493b35826678a5ec55bc88e8c8a3a9dbfdf381dce2a41b0856bb98234efc129d
|
|
BLAKE2b-256 checksum How to use checksums |
2769d96fc97c3b9791979f0951511c7273836130f868d9630fd7a072511e7631
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logSecurity for pyro-mysql 0.2.16
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 6 files in this release have been uploaded with provenance metadata.
Attestation for pyro_mysql-0.2.16-cp310-abi3-win_arm64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Dec 29, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.