1. Why connect, and what you need
A database stores data safely and lets many users query it; a Python program adds menus, checks and calculations. The program is a client; the MySQL server holds the database; the driver mysql.connector carries SQL to the server and rows back.
Install once: pip install mysql-connector-python. Import in every program: import mysql.connector (or import mysql.connector as sq).
Key terms
- Driver (connector)
A module that lets a program talk to a database server.
- Client
The program that sends requests to the server.
2. Connecting and creating a cursor
import mysql.connector
mycon = mysql.connector.connect(host="localhost", user="root",
passwd="your_password", database="school")
if mycon.is_connected():
print("Connected")
cur = mycon.cursor()
- connect() opens the session and returns a connection object.
- is_connected() returns True if it is open.
- cursor() (a method of the connection) returns a cursor, which runs statements and keeps the result.
- close() ends the session at the end of the program.
| Argument | Meaning | Example |
|---|---|---|
host | Computer running the MySQL server | "localhost" |
user | MySQL user name | "root" |
passwd (or password) | That user's password | "your_password" |
database | Database to open | "school" |
| Name | Belongs to | What it does |
|---|---|---|
cursor() | connection | Creates a cursor |
execute(sql, values) | cursor | Runs one SQL statement |
fetchone() | cursor | Next row as a tuple, or None |
fetchall() | cursor | All remaining rows as a list of tuples |
fetchmany(n) | cursor | Next n rows as a list |
rowcount | cursor (attribute) | Rows affected by the last INSERT, UPDATE or DELETE |
commit() | connection | Saves changes permanently |
close() | connection or cursor | Ends the session |
Key terms
- Connection object
Represents an open session with the server; has cursor(), commit(), close(), is_connected().
- Cursor
Runs SQL with execute() and holds the rows of a query.
3. Practice tables used in this chapter
All programs in the slides, notes and questions use these imagined tables. Every output shown was produced by running the program on exactly these rows.
| roll | name | sec | fee | house |
|---|---|---|---|---|
| 1 | Aarav | 12A | 4500 | Tagore |
| 2 | Bhavna | 12B | 4200 | Raman |
| 3 | Chetan | 12A | 4800 | Bose |
| 4 | Dia | 12C | 4200 | Tagore |
| 5 | Eshan | 12B | 5000 | Raman |
| icode | iname | price | qty |
|---|---|---|---|
| 101 | Notebook | 60 | 40 |
| 102 | Gel pen | 15 | 120 |
| 103 | Geometry box | 150 | 12 |
| 104 | Highlighter | 35 | 0 |
| 105 | Stapler | 90 | 8 |
| pid | pname | dept | age |
|---|---|---|---|
| 11 | Meera | Dental | 34 |
| 12 | Kabir | ENT | 8 |
| 13 | Farah | Dental | 61 |
| 14 | Rohan | Ortho | 45 |
| 15 | Sana | ENT | 27 |
4. Reading rows: fetchone(), fetchall(), fetchmany(n)
After cur.execute("SELECT …"):
- fetchone() — the next row as a tuple; None when no row is left.
- fetchall() — all remaining rows as a list of tuples;
[]when none are left. - fetchmany(n) — the next n rows as a list.
The cursor keeps one pointer that only moves forward; to read again, execute again. Each tuple holds the selected columns in order, so row[0] is the first selected column.
import mysql.connector
mycon = mysql.connector.connect(host="localhost", user="root",
passwd="your_password", database="school")
cur = mycon.cursor()
cur.execute("SELECT roll FROM student ORDER BY roll")
a = cur.fetchmany(2)
b = cur.fetchone()
c = cur.fetchall()
print(a)
print(b)
print(c)
Output:
[(1,), (2,)]
(3,)
[(4,), (5,)]
| Call | Returns |
|---|---|
| fetchone() call 1 | ('Bhavna',) |
| fetchone() call 2 | ('Eshan',) |
| fetchone() call 3 | None |
Key terms
- Result set
The rows returned by a SELECT, read through the cursor.
- Row tuple
One row of a result, e.g. (1, 'Aarav', '12A', 4500, 'Tagore').
5. Changing the data with commit() and rowcount
INSERT, UPDATE and DELETE are run with execute() like any query, but mysql.connector does not autocommit: the change stays in an open transaction until mycon.commit(). Closing without commit discards it.
cur.rowcount (an attribute, no brackets) is the number of rows the last INSERT, UPDATE or DELETE affected.
import mysql.connector
mycon = mysql.connector.connect(host="localhost", user="root",
passwd="your_password", database="shop")
cur = mycon.cursor()
cur.execute("UPDATE item SET qty = qty + 25 WHERE qty < 15")
mycon.commit()
print("Restocked:", cur.rowcount)
cur.execute("DELETE FROM item WHERE price > 100")
mycon.commit()
print("Removed:", cur.rowcount)
Output:
Restocked: 3
Removed: 1
| Statement | Rows matched | Printed |
|---|---|---|
UPDATE … WHERE qty < 15 | Geometry box, Highlighter, Stapler | Restocked: 3 |
DELETE … WHERE price > 100 | Geometry box | Removed: 1 |
Key terms
- commit()
Connection method that makes changes permanent.
- rowcount
Cursor attribute: rows affected by the last statement.
- Transaction
A group of changes saved together by commit().
6. Values from variables: %s and format()
Placeholders: write %s for each value and pass a tuple: cur.execute("SELECT * FROM student WHERE roll = %s", (r,)). Text is quoted by the driver; the comma in (r,) makes a one-value tuple.
format(): build the string first: q = "SELECT * FROM student WHERE house = '{}'".format(h); text values need quotes written around {}.
Placeholders are safer with user input (they prevent SQL injection).
Complete program with input:
import mysql.connector
con = mysql.connector.connect(host="localhost", user="root",
passwd="your_password", database="shop")
cur = con.cursor()
code_no = int(input("Item code: "))
name = input("Item name: ")
price = int(input("Price: "))
qty = int(input("Quantity: "))
cur.execute("INSERT INTO item VALUES (%s, %s, %s, %s)", (code_no, name, price, qty))
con.commit()
cur.execute("SELECT * FROM item WHERE icode = %s", (code_no,))
print()
print("Saved:", cur.fetchone())
con.close()
With inputs 106, Eraser, 10 and 50 the last line printed is Saved: (106, 'Eraser', 10, 50).
Catching errors: except mysql.connector.Error: catches errors reported by the database (e.g. a duplicate primary key).
%s placeholder | format() | |
|---|---|---|
| How the value gets in | Sent separately in a tuple | Pasted into the SQL text |
| Quotes for text values | Added by the driver | You must write them |
| Safe with user input? | Yes | No: input can change the query |
| Example | execute(q, (60,)) | q = "… <= {}".format(60) |
| Blank | Usual answer |
|---|---|
| Create a cursor | con.cursor() |
| Run the query | cur.execute(q) or cur.execute(q, values) |
| Save a change | con.commit() |
| All rows / one row | cur.fetchall() / cur.fetchone() |
| Rows changed | cur.rowcount |
Key terms
- Parameterised query
A query with %s placeholders whose values are passed separately.
- SQL injection
Typed text that changes a query when it is pasted into the SQL string.
Exam tips
Common mistakes
cur = con.cursorwithout brackets;cur.rowcount()with brackets.- Fetching before
execute(); indexing theNonethatfetchone()returns. - No
commit()after INSERT, UPDATE or DELETE. execute(q, 5)instead ofexecute(q, (5,)).- Missing quotes around text in a
format()query.
How marks are usually awarded
- Output questions: the exact printed form of tuples and lists (brackets, quotes, commas).
- Fill-the-missing-statement: one mark per statement.
- Programs (4–5 marks): connection and cursor, correct query with placeholders,
commit()where data changes, display/rowcount, closing.
About the outputs in SOYL practice: programs are shown with mysql.connector, as in the syllabus; their outputs were produced by running the same programs on the same rows with Python's built-in database module, using only whole-number and text columns so the printed values match.