Skip to main content

python-pymysql

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.

Quellinformationen

Repository
the-perfect-developer/the-perfect-opencode
Letzte Quellaktivität
5. März 2026 um 15:33
Erkannte Sprache von SKILL.md
Englisch
Sterne
12
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
python-pymysql
description
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.
# PyMySQL Best Practices PyMySQL is a pure-Python MySQL client library implementing the DB-API 2.0 specification (PEP 249). It supports MySQL >= 5.7 and MariaDB >= 10.3 on Python >= 3.7. ## Installation ```bash pip install PyMySQL # For SHA-256 / caching_sha2_password authentication: pip install "PyMySQL[rsa]" ``` ## Establishing a Connection Use `pymysql.connect()` as the entry point. Always specify `charset='utf8mb4'` and use context managers to guarantee cleanup. ```python 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) ) ``` ### Key Connection Parameters | Parameter | Default | Notes | |---|---|---| | `charset` | `''` | Always set `utf8mb4` for full Unicode support | | `cursorclass` | `Cursor` | Use `DictCursor` for dict rows; `SSCursor` for large result sets | | `autocommit` | `False` | Keep `False`; commit/rollback explicitly | | `connect_timeout` | `10` | Seconds before connection attempt fails | | `read_timeout` | `None` | Set to prevent hung reads | | `write_timeout` | `None` | Set to prevent hung writes | | `ssl_ca` | `None` | Path to CA cert for TLS connections | ## Context Manager Usage Connections and cursors implement the context manager protocol. Use `with` blocks to ensure proper resource cleanup. ```python # 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**: Using `with connection:` handles transaction commit/rollback but does **not** close the connection. Call `connection.close()` explicitly or manage it via a pool. ## Parameterized Queries (SQL Injection Prevention) Always pass values as the second argument to `execute()`. Never use string formatting or concatenation to build SQL. ```python # 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 risk ``` Use `cursor.mogrify(query, args)` to preview the interpolated query string during debugging. ## Cursor Types | Cursor Class | Returns | Buffered | Use Case | |---|---|---|---| | `Cursor` | tuple | Yes | Default; small-to-medium result sets | | `DictCursor` | dict | Yes | When column-name access is needed | | `SSCursor` | tuple | No | Large result sets; memory-constrained | | `SSDictCursor` | dict | No | Large result sets with dict access | Pass `cursorclass` at connection time (global default) or per-cursor: ```python # Per-cursor override with connection.cursor(pymysql.cursors.DictCursor) as cursor: cursor.execute("SELECT * FROM users") rows = cursor.fetchall() # list of dicts ``` For large tables, prefer `SSCursor` and iterate without calling `fetchall()`: ```python with connection.cursor(pymysql.cursors.SSCursor) as cursor: cursor.execute("SELECT * FROM large_table") for row in cursor: # streams row-by-row process(row) ``` ## Transaction Management PyMySQL defaults to `autocommit=False`. Explicitly commit successful work and roll back on errors. ```python try: 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() raise ``` Call `connection.begin()` to start a transaction block explicitly when needed. ## Bulk Inserts with `executemany()` Use `executemany()` for inserting multiple rows. PyMySQL batches the statements up to `Cursor.max_stmt_length` (1 MB) for efficiency. ```python records = [ ("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() ``` ## Fetching Rows | Method | Returns | Notes | |---|---|---| | `fetchone()` | single row or `None` | Efficient for single-row lookups | | `fetchmany(size)` | list of rows | Page through results | | `fetchall()` | list of all rows | Avoid on large result sets | ```python 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") ``` ## Error Handling Catch PyMySQL exceptions from `pymysql.err`: ```python import 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 raise ``` Key exception classes: - `pymysql.err.IntegrityError` — constraint violations (duplicate key, FK) - `pymysql.err.OperationalError` — connection / server errors - `pymysql.err.ProgrammingError` — SQL syntax errors, wrong param count - `pymysql.err.DataError` — invalid data for column type - `pymysql.err.DatabaseError` — base class for all DB errors ## Connection Health Check Use `connection.ping(reconnect=True)` to check liveness before executing queries in long-lived connections (e.g., background workers): ```python connection.ping(reconnect=True) with connection.cursor() as cursor: cursor.execute(query) ``` ## Reading Config from `my.cnf` Avoid hardcoding credentials. Use `read_default_file` to read from a MySQL option file: ```python connection = pymysql.connect( read_default_file="~/.my.cnf", read_default_group="client", database="mydb", charset="utf8mb4", cursorclass=pymysql.cursors.DictCursor, ) ``` `~/.my.cnf` example: ```ini [client] host = db.internal user = app_user password = secret ``` ## Quick Reference ```python import 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() ``` ## Additional Resources For detailed patterns and advanced usage, consult: - **`references/connection-patterns.md`** — Connection pooling, SSL/TLS configuration, timeout tuning, `my.cnf` patterns - **`references/cursor-guide.md`** — Cursor type selection, streaming large result sets, stored procedures, `mogrify` debugging
Auf GitHub ansehen