Python to MySQL Interface
Python to MySQL Interface
MySQL Connector/Python
• MySQL Connector/Python is a so4ware interface for communica9ng to MySQL servers from
Python programs.
• The interface is compliant with Python Database API Specifica9on v2.0 (PEP 249).
• This interface is supported by Oracle, which maintains MySQL.
• There are Python DB-API interfaces provided by third-par9es as well – Example PyMySQL.
Note: pip is "Preferred Installer Program" – used for installing and managing Python packages.
Connec5ng to a database
The connect() func9on sets up a connec9on, establishing a session with the MySQL server.
dbconn = mysql.connector.connect(
host = <database server name or IP address>,
user = <user name>,
password = <passoword>,
database = <database name>
)
Example:
dbconn = mysql.connector.connect(
host = 'localhost',
user = 'root',
password = 'mypassword',
database = 'learn'
)
Connec9on arguments:
host – Database server name or IP address. 'localhost' refers to the host on which the Python
program is execu9ng. 127.0.0.1 (loopback IP address) can also be used to refer to the local
computer. If the argument is not provided, 127.0.0.1 is used.
user – User name. If this argument is not provided ODBC is used as the user name.
database – Default database for subsequent statements. No default database is set if this argument
is not given. Database can be selected later by execu9ng a USE command.
Note: At least one argument should be specified for the connect() func9on.
Important: As per CBSE sample ques9on paper, only database argument is op9onal. This is because
this argument does not have a fallback value unlike the others.
• Cursors created from the same connec9on are not isolated, i.e., any changes done to the
database by a cursor are immediately visible to the other cursors.
Example:
# Create a cursor
cur = dbconn.cursor()
Func@on Descrip@on
fetchone() Fetches a single record from the resultset. The record is returned as a
tuple.
fetchmany(size=1) Fetches mul9ple records from the resultset. The maximum number of
records that can be fetched is specified by the size argument. The
records are returned as a list of tuples.
• The fetch func9ons return records in the same order as returned by the database server.
• The fetch is done star9ng from the first record that is yet to be fetched.
No more record is available to be fetched when any of the following condi9ons occur.
Follow this when wri@ng programs – A4er any of the above condi9ons is reached, no more fetch
func9on calls should be done on the cursor. But, do not men9on this point when answering theory
ques9ons.
cur.fetchone()
print(cur.rowcount) # prints 1
cur.fetchmany(3)
print(cur.rowcount) # prints 4
cur.fetchone()
print(cur.rowcount) # prints 5
cur.fetchmany(2)
print(cur.rowcount) # prints 7
cur.fetchone()
print(cur.rowcount) # prints 7
INSERT/UPDATE/DELETE Commands
DML commands that change data (INSERT/UPDATE/DELETE) are executed the same way as SELECT –
by calling execute() func9on of cursor. A4er execute() func9on completes, the rowcount
property will have the number of records affected by the INSERT/UPDATE/DELETE command.
Data changes done by INSERT/UPDATE/DELETE commands are visible to other users/sessions only
a4er commit() func9on is called on the connec9on object. If commit() is not called before closing
the connec9on, all the changes done from the previous commit (or opening of the connec9on) are
discarded.
Example: Let’s assume a table named Result has only two integer columns, RollNum & Marks and is
ini9ally empty.
def showcount(dbconn):
cur = dbconn.cursor()
cur.execute("SELECT * FROM Result")
cur.fetchall()
print(cur.rowcount)
showcount(dbconn) # prints 0
cur = dbconn.cursor()
cur.execute(
"INSERT INTO Result VALUES (101, 97), (102, 98)")
print(cur.rowcount) # prints 2
showcount(dbconn) # prints 2
dbconn.commit() # insert of 2 rows committed
cur = dbconn.cursor()
cur.execute(
"INSERT INTO Result VALUES (103, 96), (104, 95)")
print(cur.rowcount) # prints 2
showcount(dbconn) # prints 4
DDL Commands
DDL commands (CREATE, ALTER, DROP, TRUNCATE, etc) are also executed the same way. A4er the
execute() func9on completes, the rowcount property will be zero.
Unlike DML commands, DDL commands are not related to commit() func9on calls. DDL command
changes take place immediately.
Example:
dbconn = getconnection()
cur = dbconn.cursor()
cur.execute("TRUNCATE TABLE Result")
print(cur.rowcount) # prints 0
showcount(dbconn) # prints 0
The above code deletes all records from Result table even though the commit() func9on is not
called. However, the below code does not make any change to the data.
dbconn = getconnection()
cur = dbconn.cursor()
cur.execute("DELETE FROM Result")
print(cur.rowcount) # prints 0
showcount(dbconn) # prints 0
Database Transac5ons
A database transac9on is a unit of work consis9ng of one or more DML opera9ons that are
commi[ed (saved and made permanent) as a single unit. When a transac9on contains mul9ple
opera9ons, either all the opera9ons are saved or none of them is saved.
The commit() func9on described earlier commits the currently ac9ve transac9on. A transac9on is
automa9cally started for a database connec9on when a DML command (including SELECT) is
executed and no transac9on is currently ac9ve. All subsequent DML opera9ons become part of the
ac9ve transac9on. The transac9on is commi[ed when the commit() func9on is called.
When the database connec9on is closed while a transac9on is ac9ve, all data changes that are part
of the ac9ve transac9on are discarded.
DDL commands do not start or join any transac9on. If a DDL command is executed when a
transac9on is ac9ve, the ac9ve transac9on is commi[ed before execu9ng the DDL command.
Method/Property Descrip@on
start_transac9on() Explicitly start a transac9on.
rollback() Rolls back the currently ac9ve transac9on (if any)
in_transac9on Boolean property that returns True when a transac9on is ac9ve for the
connec9on.
autocommit Property when set to True will automa9cally commit the ac9ve
transac9on (if any) when the database connec9on is closed.
Parameterized Statements
The cursor execute() method has an op9onal argument that can be used to provide values for
parameters in the statement string.
data = (
False,
"Howlin' Wolf",
5.5,
datetime.datetime(2012, 3, 23, 11, 12, 33), datetime.time(10, 20,
30, 144)
)
cur.execute(stmt, data)
print(cur.statement)
The above code executes a query with five parameters. Each of the parameters occurs in the
statement string as a %s. The values for the parameters are given as a tuple or a list. The number of
elements in the tuple/list should exactly match the number of occurrences of %s in the statement
string.
The cursor statement property returns the full statement got a4er replacing parameters. This is the
statement sent to the MySQL server. The print() func9on in the above example will print:
INSERT INTO MyTable VALUES (False, 'Howlin\' Wolf', 5.5, '2012-03-23 11:12:33', '10:20:30.000144')
No9ce that the parameters are forma[ed as required by MySQL, including escaping in strings.
Note that the formalng done by execute() is not same as using Python string formalng operator
%. In the above example, (stmt % data) will give the following invalid SQL statement:
INSERT INTO MyTable VALUES (False, Howlin' Wolf, 5.5, 2012-03-23 11:12:33, 10:20:30.000144)
In the earlier example, having the statement string and the parameter values as below will have the
same effect.
stmt = """INSERT INTO MyTable VALUES (
%(flag)s,
%(name)s,
%(amount)s,
%(start_datetime)s,
%(end_time)s
)"""
data = {
'flag':False,
'name':"Howlin' Wolf",
'amount':5.5,
'start_datetime':datetime.datetime(2012, 3, 23, 11, 12, 33),
'end_time':datetime.time(10, 20, 30, 144)
}
Here, the parameters are referred to by names and values for the parameters are given as a
dic9onary. Each of the parameters occurs in the statement string as a %(parameter_name)s. It is an
error if any of the named parameters present in the statement string is not found in the dic9onary.
However, any addi9onal unused parameter in the dic9onary does not cause error.
The parameter values are forma[ed by execute() func9on based on the data type of the
parameter values.
The str.format() func9on can take mul9ple posi9onal arguments and mul9ple named
arguments. The forma[ed string is created by replacing the parameters in the format string with the
arguments.
Example:
# Positional arguments with auto numbering
stmtfmt = "INSERT INTO MyTable VALUES({}, {}, {})"
stmt = stmtfmt.format(100, 200, 300)
print (stmt)
# Named arguments
stmtfmt = "INSERT INTO MyTable VALUES({num}, {amt1}, {amt2})"
stmt = stmtfmt.format(num=100, amt1=200, amt2=300)
print (stmt)
All of the above five formalng gives the same forma[ed string:
Python str.format() DOES NOT work well for the following values:
• String – Needs to be quoted in the format string. There no support for escape sequences.
Prone to SQL injec9on – should not be used.
• Nega9ve 9medelta values and 9medelta values greater than or equal to 1 day – The default
Python formalng does not match MySQL format.