On this page
The Python and MySQL connectivity question is one of the few long questions in CBSE computer science that follows a fixed pattern. Once you know the six steps, you can write most answers from memory. This post covers what the syllabus lists, walks through each step with code we ran against a MySQL 8.4 server, and explains the errors that cost marks.
What does the syllabus ask for?
The CBSE Computer Science curriculum for Class XII (2026-27) lists, in the Database Management unit: connecting SQL with Python, performing insert, update and delete queries using a cursor, displaying data with connect(), cursor(), execute(), commit(), fetchone(), fetchall() and rowcount, and using the %s format specifier or format() to build queries. The practical exam's report file also needs at least four programs based on Python and SQL connectivity. The NCERT SQL chapter does not cover this part, so the official MySQL Connector/Python documentation is the best reference.
The examples below use a table student(rollno, name, marks) in a database called school, with three rows: (1, Asha, 82), (2, Ravi, 64) and (3, Meera, 91). For tables and keys, see our guide to database concepts for CBSE.
How do you connect and create a cursor?
import mysql.connector
con = mysql.connector.connect(host="localhost", user="student",
password="lab123", database="school")
if con.is_connected():
print("Connected")
cur = con.cursor()connect() returns a connection object. The cursor is what sends queries and holds results. The module comes from the mysql-connector-python package; if import fails, install it with pip install mysql-connector-python.
How do you read data with fetchall and fetchone?
cur.execute("SELECT * FROM student")
rows = cur.fetchall()
for row in rows:
print(row)
print(cur.rowcount)This prints (1, 'Asha', 82), (2, 'Ravi', 64) and (3, 'Meera', 91), each as a tuple, and then 3. fetchall() returns a list of tuples. fetchone() returns just the next row as a tuple, or None when there are no more.
The rowcount documentation says it gives the number of rows returned for SELECT statements, or the number affected by INSERT, UPDATE or DELETE. With the default cursor, the count for a SELECT is known only as rows are fetched. In our test it was 0 straight after execute (the documentation says it may be −1), 1 after one fetchone, and 3 after fetchall, so print rowcount after fetching.
How do you insert, update and delete, and why commit?
roll, name, marks = 4, "Kabir", 75
cur.execute("INSERT INTO student VALUES (%s, %s, %s)", (roll, name, marks))
con.commit()
print(cur.rowcount, "row inserted") # 1 row inserted
cur.execute("UPDATE student SET marks = marks + 5 WHERE marks < {}".format(70))
con.commit()
print(cur.rowcount, "row updated") # 1 row updated (Ravi, now 69)The commit() documentation says that "by default Connector/Python does not autocommit", so you must call commit() after every change. We tested this: an insert executed without commit() had vanished when we reconnected. The CBSE marking scheme gives a mark for executing the query with commit.
Should you use %s or format()?
Both appear in the syllabus, and they work differently.
%s with a tuple: cur.execute(query, (value,)) passes values separately, and the connector converts them. The execute() documentation describes this %s style. You do not put quotes around %s, even for text.
format(): builds the full query string first. Text values then need quotes inside the string, as in "SELECT * FROM student WHERE name = '{}'".format("Ravi").
In real programs, prefer %s with a tuple. The OWASP guide to SQL injection prevention lists parameterised queries as the first defence, because the database can then always tell code from data. Building queries from user input with format() lets a crafted input change the query.
What does a full exam answer look like?
The 2026-27 CBSE sample question paper asks for a program that changes one book's title in a table. The marking scheme awards half marks for importing the connector, creating the connection and creating the cursor, one mark for the query, one for executing it with commit, and half for closing the connection. In the same shape, here is a delete:
cur.execute("DELETE FROM student WHERE rollno = %s", (4,))
con.commit()
print(cur.rowcount, "row deleted")
cur.close()
con.close()What mistakes cost marks?
No commit() after insert, update or delete.
A single value without a comma. (4) is just 4. Passing it raised "Could not process parameters" in our test; (4,) works.
Quotes around %s, or missing quotes around text inside format().
Running a new query with rows left unread. After fetchone(), executing again on the same cursor raised "Unread result found". Fetch the rest or use a fresh cursor.
Forgetting to close the cursor and connection.
A practice routine for connectivity
Recall practice works better than rereading. In Roediger and Karpicke's experiments, students who tested themselves remembered more after a week than those who restudied.
Day 1: Write the six steps from memory, then the select program. Run it.
Day 2: Write insert, update and delete programs that take values with input() and use %s.
Day 4: Combine them into a menu-driven program for your report file.
Day 7: Write the sample paper answer on paper in 10 minutes, then check it against the marking scheme.
When the SQL inside the program is the problem, our guide to SQL for CBSE covers the queries. If you are not sure where to start, Fermi's AI tutor works out what you already know and builds a plan for the session.
Open the school lab's MySQL today, create the student table above and run the select program.



