Loading...
Loading...
This skill should be used when the user asks to "connect to MySQL with PyMySQL", "use PyMySQL in Python", "query a MySQL database with Python", "set up PyMySQL", or needs guidance on PyMySQL best practices, transactions, parameterized queries, or cursor types.
npx skill4agent add the-perfect-developer/the-perfect-opencode python-pymysqlpip install PyMySQL
# For SHA-256 / caching_sha2_password authentication:
pip install "PyMySQL[rsa]"pymysql.connect()charset='utf8mb4'import pymysql
import pymysql.cursors
connection = pymysql.connect(
host="localhost",
user="app_user",
password="secret",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
connect_timeout=10,
read_timeout=30,
write_timeout=30,
autocommit=False, # explicit transaction control (recommended)
)| Parameter | Default | Notes |
|---|---|---|
| | Always set |
| | Use |
| | Keep |
| | Seconds before connection attempt fails |
| | Set to prevent hung reads |
| | Set to prevent hung writes |
| | Path to CA cert for TLS connections |
with# Connection as context manager — commits on success, rolls back on exception
with pymysql.connect(**db_config) as connection:
with connection.cursor() as cursor:
cursor.execute("SELECT id, email FROM users WHERE active = %s", (1,))
rows = cursor.fetchall()Note: Usinghandles transaction commit/rollback but does not close the connection. Callwith connection:explicitly or manage it via a pool.connection.close()
execute()# Correct — parameterized
cursor.execute(
"INSERT INTO orders (user_id, amount) VALUES (%s, %s)",
(user_id, amount),
)
# Named placeholders with dict
cursor.execute(
"SELECT * FROM products WHERE category = %(cat)s AND price < %(max_price)s",
{"cat": "electronics", "max_price": 500},
)
# WRONG — never do this
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'") # SQL injection riskcursor.mogrify(query, args)| Cursor Class | Returns | Buffered | Use Case |
|---|---|---|---|
| tuple | Yes | Default; small-to-medium result sets |
| dict | Yes | When column-name access is needed |
| tuple | No | Large result sets; memory-constrained |
| dict | No | Large result sets with dict access |
cursorclass# Per-cursor override
with connection.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall() # list of dictsSSCursorfetchall()with connection.cursor(pymysql.cursors.SSCursor) as cursor:
cursor.execute("SELECT * FROM large_table")
for row in cursor: # streams row-by-row
process(row)autocommit=Falsetry:
with connection.cursor() as cursor:
cursor.execute(
"UPDATE accounts SET balance = balance - %s WHERE id = %s",
(amount, from_id),
)
cursor.execute(
"UPDATE accounts SET balance = balance + %s WHERE id = %s",
(amount, to_id),
)
connection.commit()
except Exception:
connection.rollback()
raiseconnection.begin()executemany()executemany()Cursor.max_stmt_lengthrecords = [
("alice@example.com", "hash1"),
("bob@example.com", "hash2"),
]
with connection.cursor() as cursor:
cursor.execute("TRUNCATE TABLE staging_users")
cursor.executemany(
"INSERT INTO users (email, password_hash) VALUES (%s, %s)",
records,
)
connection.commit()| Method | Returns | Notes |
|---|---|---|
| single row or | Efficient for single-row lookups |
| list of rows | Page through results |
| list of all rows | Avoid on large result sets |
cursor.execute("SELECT id, name FROM users WHERE id = %s", (user_id,))
row = cursor.fetchone()
if row is None:
raise ValueError(f"User {user_id} not found")pymysql.errimport pymysql.err
try:
with connection.cursor() as cursor:
cursor.execute(sql, args)
connection.commit()
except pymysql.err.IntegrityError as exc:
connection.rollback()
# duplicate key, foreign key violation, etc.
raise
except pymysql.err.OperationalError as exc:
# connection dropped, timeout, server gone away
raise
except pymysql.err.ProgrammingError as exc:
# bad SQL syntax, wrong number of params
raisepymysql.err.IntegrityErrorpymysql.err.OperationalErrorpymysql.err.ProgrammingErrorpymysql.err.DataErrorpymysql.err.DatabaseErrorconnection.ping(reconnect=True)connection.ping(reconnect=True)
with connection.cursor() as cursor:
cursor.execute(query)my.cnfread_default_fileconnection = pymysql.connect(
read_default_file="~/.my.cnf",
read_default_group="client",
database="mydb",
charset="utf8mb4",
cursorclass=pymysql.cursors.DictCursor,
)~/.my.cnf[client]
host = db.internal
user = app_user
password = secretimport pymysql
import pymysql.cursors
# Connect
conn = pymysql.connect(
host="localhost", user="u", password="p", database="db",
charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor,
)
# Query
with conn.cursor() as cur:
cur.execute("SELECT * FROM t WHERE id = %s", (1,))
row = cur.fetchone()
# Write + commit
with conn.cursor() as cur:
cur.execute("INSERT INTO t (col) VALUES (%s)", ("val",))
conn.commit()
# Bulk insert
with conn.cursor() as cur:
cur.executemany("INSERT INTO t (a, b) VALUES (%s, %s)", rows)
conn.commit()
conn.close()references/connection-patterns.mdmy.cnfreferences/cursor-guide.mdmogrify