Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
3 views

Python to MySQL Interface

The document provides a comprehensive guide on using MySQL Connector/Python to interact with MySQL databases, including installation, connection setup, executing SQL commands, and fetching results. It covers the creation of cursors, data type mapping, and the handling of transactions, including DML and DDL commands. Additionally, it explains the use of parameterized statements to prevent SQL injection and the formatting of data types for MySQL queries.

Uploaded by

asdf lkjh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Python to MySQL Interface

The document provides a comprehensive guide on using MySQL Connector/Python to interact with MySQL databases, including installation, connection setup, executing SQL commands, and fetching results. It covers the creation of cursors, data type mapping, and the handling of transactions, including DML and DDL commands. Additionally, it explains the use of parameterized statements to prevent SQL injection and the formatting of data types for MySQL queries.

Uploaded by

asdf lkjh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

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.

Installa5on of MySQL Connector/Python package


pip install mysql-connector-python

Note: pip is "Preferred Installer Program" – used for installing and managing Python packages.

Impor5ng MySQL Connector module in Python


import mysql.connector
Or
import mysql.connector as mysql

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>
)

Or, in case of import as.


dbconn = mysql.connect(...

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.

password – Can be omi[ed when user does not have password.

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.

Crea5ng a Cursor and Execu5ng a SQL Statement


• Cursors are objects used for execu9ng statements on a database and for fetching the results
of the executed statement.

• 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.

• Cursors created from different connections are isolated.

A cursor is created by the cursor() func9on of the connec9on object.

Example:

# Create a cursor
cur = dbconn.cursor()

# Execute a SQL statement


cur.execute('SELECT EmpName, DOJ FROM Empl')

Fetching Results from a SQL Query


A4er execu9ng a SELECT statement using execute(), the resultset, set of records retrieved by the
query, is available in the cursor. The records in the resultset can be fetched using any of the following
func9ons of cursor.

Func@on Descrip@on
fetchone() Fetches a single record from the resultset. The record is returned as a
tuple.

Returns None when no record is available to be fetched.

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.

For example cur.fetchmany(3) will fetch 3 records if the number of


records available to be fetched is 3 or higher, else it fetches all the
remaining records.

Returns an empty list when no record is available to be fetched.


fetchall() Fetches all the records from the resultset. The records are returned as a
list of tuples.

Returns an empty list when no record is available to be fetched.

• 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.

Example: Let’s say the query returned 7 records.


cur.fetchone() # 1st record as tuple
cur.fetchmany(3) # 2nd, 3rd and 4th records as list
cur.fetchone() # 5th record as tuple
cur.fetchmany(2) # 6th and 7th records as list
cur.fetchone() # Returns None

No more record is available to be fetched when any of the following condi9ons occur.

• fetchone() returned None


• fetchmany() returned fewer records than the size argument value
• fetchall() is called

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.

Cursor rowcount property for SELECT queries


For SELECT queries, the rowcount property of cursor gives the number of fetched rows 9ll now.

• When the cursor object is created, rowcount will be -1.


• A4er execute() it will become 0.
• Then, it will get updated based on the fetch calls.

Example: Let’s say the query returned 7 records.


cur = dbconn.cursor()
print(cur.rowcount) # prints -1

cur.execute('<A SELECT statement returning 7 rows>')


print(cur.rowcount) # prints 0

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

Data Type Mapping


MySQL data returned by queries are mapped to corresponding Python data types as below.

MySQL Data Type Python Data Type


All integer types (including UNSIGNED) int
TINYINT, SMALLINT, MEDIUMINT, BIGINT
BOOLEAN int
CHAR and VARCHAR str
DECIMAL decimal.Decimal
FLOAT and DOUBLE float
DATE date9me.date
DATETIME and TIMESTAMP date9me.date9me
TIME date9me.9medelta

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)

dbconn = getconnection() # create new db connection

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

dbconn.close() # insert of 2 rows NOT committed

dbconn = getconnection() # create new db connection


showcount(dbconn) # prints 2

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

dbconn.close() # Closing without committing

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

dbconn.close() # Closing without committing

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.

Other transac9on control func9ons and proper9es in database connec9on:

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.

Specifying parameters by posi@on


stmt = 'INSERT INTO MyTable VALUES (%s, %s, %s, %s, %s)'

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)

Specifying parameters by name (Preferred approach)

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.

FormaPng by data type

The parameter values are forma[ed by execute() func9on based on the data type of the
parameter values.

Parameter Value Data Type FormaPng


Any numeric data type As number without loss of precision.

Boolean As TRUE or FALSE.

String As single quote enclosed string with MySQL escape sequences.

date9me.date As single quote enclosed string in 'YYYY-MM-DD' format.

date9me.date9me As single quote enclosed string in the format:

'YYYY-MM-DD hh:mm:ss' if there is no microsecond


'YYYY-MM-DD hh:mm:ss.ffffff' if microseconds present
date9me.9me As single quote enclosed string in the format:

' hh:mm:ss' if there is no microsecond


' hh:mm:ss.ffffff' if microseconds present

date9me.9medelta As single quote enclosed string in the format:

' hh:mm:ss' if there is no microsecond


' hh:mm:ss.ffffff' if microseconds present

Minimum length of hh is 2. It will be longer if the 9medelta value


is larger.

FormaPng parameter values with Python str.format()

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)

# Positional arguments with manual numbering


stmtfmt = "INSERT INTO MyTable VALUES({1}, {2}, {0})"
stmt = stmtfmt.format(300, 100, 200)
print (stmt)

# Named arguments
stmtfmt = "INSERT INTO MyTable VALUES({num}, {amt1}, {amt2})"
stmt = stmtfmt.format(num=100, amt1=200, amt2=300)
print (stmt)

# Mix of named arguments and auto numbering


stmtfmt = "INSERT INTO MyTable VALUES({num}, {}, {amt})"
stmt = stmtfmt.format(200, num=100, amt=300)
print (stmt)

# Mix of named arguments and manual numbering


stmtfmt = "INSERT INTO MyTable VALUES({num}, {0}, {amt})"
stmt = stmtfmt.format(200, num=100, amt=300)
print (stmt)

All of the above five formalng gives the same forma[ed string:

INSERT INTO MyTable VALUES(100, 200, 300)

Python str.format() works well for the following values:


• Numeric data types
• Boolean
• date, 9me and date9me – Needs to be quoted in the format string
• Posi9ve 9medelta values less than 1 day – Needs to be quoted in the format 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.

Using str.format() for formalng SQL commands is not recommended.

You might also like