Hopsworks Async MySQL Driver (aiomysql)
The `hopsworks-aiomysql` library provides an asynchronous MySQL client for Python, distributed by Logical Clocks, primarily for use within the Hopsworks ecosystem. It is effectively a distribution of the popular `aiomysql` library (currently version 0.2.2) and follows its API. It's actively maintained but release cadence is tied to Hopsworks platform updates rather than independent `aiomysql` releases.
Common errors
-
ModuleNotFoundError: No module named 'hopsworks_aiomysql'
cause Incorrect import statement. The installed package name differs from the actual Python module name to be imported.fixChange `from hopsworks_aiomysql import ...` to `from aiomysql import ...`. -
TypeError: object aiomysql.connection.Connection can't be used in 'await' expression
cause Attempting to `await` a connection object directly instead of using `async with` for context management, or forgetting `await` for methods that return awaitables.fixEnsure `pool.acquire()` and `conn.cursor()` are used with `async with` (e.g., `async with pool.acquire() as conn:`) and other async methods are explicitly awaited (e.g., `await cur.execute(...)`). -
RuntimeWarning: coroutine 'create_pool' was never awaited
cause An asynchronous function or coroutine was called but the `await` keyword was omitted.fixAdd `await` before the coroutine call, e.g., `pool = await create_pool(...)`. -
OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)")
cause The MySQL server is not running, is inaccessible from the client machine, or the provided host/port/credentials are incorrect.fixVerify that your MySQL server is running and accessible from the machine where your Python script is executing. Check firewall rules, network connectivity, and ensure the `host`, `port`, `user`, `password`, and `db` parameters are correct.
Warnings
- gotcha The installed package is `hopsworks-aiomysql`, but the Python module to import and use is `aiomysql`. Attempts to `from hopsworks_aiomysql import ...` will result in a `ModuleNotFoundError`.
- gotcha The `hopsworks-aiomysql` package bundles its own `aiomysql` source internally but also declares `aiomysql` as an `install_requires` dependency. This unusual setup can lead to confusion or potential version conflicts if another version of `aiomysql` is explicitly installed or if pip's dependency resolution acts unexpectedly.
- breaking Upstream `aiomysql` (and thus `hopsworks-aiomysql` 0.2.x onwards) changed how connections and cursors are managed. Direct `await pool.acquire()` followed by `conn.close()` is deprecated in favor of `async with pool.acquire() as conn:` for proper resource handling and cleanup.
- gotcha Forgetting to `await` asynchronous calls to `aiomysql` methods (e.g., `cur.execute(...)` instead of `await cur.execute(...)`) will lead to `RuntimeWarning: coroutine was never awaited` and the operation not completing, potentially causing hangs or unexpected behavior.
Install
-
pip install hopsworks-aiomysql
Imports
- create_pool
from hopsworks_aiomysql import create_pool
from aiomysql import create_pool
- connect
from hopsworks_aiomysql import connect
from aiomysql import connect
Quickstart
import asyncio
import os
from aiomysql import create_pool
async def main():
# Database connection details, preferably from environment variables
pool = await create_pool(
host=os.environ.get('MYSQL_HOST', '127.0.0.1'),
port=int(os.environ.get('MYSQL_PORT', '3306')),
user=os.environ.get('MYSQL_USER', 'root'),
password=os.environ.get('MYSQL_PASSWORD', 'password'),
db=os.environ.get('MYSQL_DB', 'test_db'),
autocommit=True,
minsize=1,
maxsize=5
)
print("Connection pool created.")
async with pool.acquire() as conn:
# 'conn' is an aiomysql.connection.Connection object
async with conn.cursor() as cur:
# 'cur' is an aiomysql.cursors.Cursor object
await cur.execute("SELECT 1+1;")
(result,) = await cur.fetchone()
print(f"Query result: {result}")
# Ensure the pool is closed gracefully
pool.close()
await pool.wait_closed()
print("Connection pool closed.")
if __name__ == '__main__':
asyncio.run(main())