Python Unit 3 Notes
Python Unit 3 Notes
MySQL Connector/Python enables Python programs to access MySQL databases, using an API that is
compliant with the Python Database API Specification v2.0 (PEP 249). It is written in pure Python and
does not have any dependencies except for the Python Standard Library.
After installing the MySQL Python connector, you need to test it to make sure that it is working correctly
and you are able to connect to the MySQL database server without any issues. To verify the installation,
you use the following steps:
Import using a import mysql.connector statement so you can use this module’s methods to
communicate with the MySQL database.
Use the connect() method of the MySQL Connector class with the required arguments to
connect MySQL. It would return a MySQLConnection object if the connection established
successfully
Use the cursor() method of a MySQLConnection object to create a cursor object to perform
various SQL operations.
The execute() methods run the SQL query and return the result.
use cursor.clsoe() and connection.clsoe() method to close open connections after your work
completes
You need to know the following detail of the MySQL server to perform the connection from Python.
Argument Description
Username The username that you use to work with MySQL Server. The
MySQL server. If you are using root then you won’t need the
password.
you are running on localhost, then you can use localhost or its
IP 127.0.0.0
Database The name of the database to which you want to connect and
The connect() constructor creates a connection to the MySQL server and returns a MySQLConnection
object.
mysql.connector.connect()
• Using this method we can connect the MySQL Database, this method accepts four required
parameters: Host, Database, User and Password .
• connect() method established a connection to the MySQL database from Python application
and returned a MySQLConnection object. Then we can use MySQLConnection object to
perform various operations on the MySQL Database.
• The Connect() method can throw an exception, i.e. Database error if one of the required
parameters is wrong. For example, if you provide a database name that is not present in
MySQL, then Python application throws an exception. So check the arguments that you are
passing to this method.
import mysql.connector
cnx.close()
Python cursor’s fetchall, fetchmany(), fetchone() to read records from database table
cursor.fetchall() fetches all the rows of a query result. It returns all the rows as a list of tuples. An empty
list is returned if there is no record to fetch.
• Define the SELECT query. Here you need to know the table and its column details.
• Execute the SELECT query using the cursor.execute() method.
• Get resultSet (all rows) from the cursor object using a cursor.fetchall().
• Iterate over the ResultSet using for loop and get column values of each row.
• Close the Python database connection.
• Catch any SQL exceptions that may come up during the process.
cursor.fetchmany(size) returns the number of rows specified by size argument. When called repeatedly,
this method fetches the next set of rows of a query result and returns a list of tuples. If no more rows are
available, it returns an empty list.
Cursor’s fetchmany() method returns the number of rows specified by size argument. the default value is
1. If the specified size is 100, then it returns 100 rows.
cursor.fetchone() method returns a single record or None if no more rows are available
• It can return a none if no rows are available in the resultset. cursor.fetchone() increments the
cursor position by one and return the next row.
Using .executemany()
It accepts two parameters:
1. A query that contains placeholders for the records that need to be inserted
2. A list that contains all records that you wish to insert
Example:
insert_reviewers_query = """
INSERT INTO reviewers
(first_name, last_name)
VALUES ( %s, %s )
"""
reviewers_records = [
("Chaitanya", "Baweja"),
("Mary", "Cooper"),
("John", "Wayne"),
("Thomas", "Stoneman"),
("Penny", "Hofstadter"),
("Mitchell", "Marsh"),
]
with connection.cursor() as cursor:
cursor.executemany(insert_reviewers_query, reviewers_records)
connection.commit()
In the script above, you pass both the query and the list of records as arguments to .executemany(). These
records could have been fetched from a file or from the user and stored in the reviewers_records list.
The code uses %s as a placeholder for the two strings that had to be inserted in
the insert_reviewers_query. Placeholders act as format specifiers and help reserve a spot for a variable
inside a string. The specified variable is then added to this spot during execution.
A parameterized query is a query in which placeholders (%s) used for parameters and the parameter
values supplied at execution time. That means parameterized query gets compiled only once.
As you can see, we are passing a parameter (%s) for the values. You must supply values in place of the
placeholders (%s) before you can execute this query using a Prepared Statement. Here we provide
python variables at the position of the placeholder.
There are the main 4 reasons to use. There are main four reasons to use.
• Improves Speed: If you want to execute SQL statement/query many times, it usually reduces
execution time
• Compile Once: The main advantage of using a parameterized query is that parameterized query
compiled only once. That means when you executed the parameterized query, MySQL can just run
the SQL statement without having to recompile it. It uses an already precompiled query and directly
executes it.
Note: For a standard query, MySQL compiles query each time before executing it.
• Same Operation with Different Data: if you want to execute the same query multiple times with
different data. For example, you want to insert 200 rows in a table then you can use parameterized
query so it can compile once and execute every time with different column values.
• Preventing SQL injection attacks.
We first open a connection to the MySQL server and store the connection object in the variable mydb. We
then create a new cursor, by default a MySQLCursor object, using the connection's cursor() method.
In the terminology of databases, cursor is that area in the memory where the data fetched from the data
tables are kept once the query is executed. In essence it is the scratch area for the database. To get a
cursor, the cursor() method of connection object has to be used. There is only one parameter to this
method -- the class that implements cursor behavior. This parameter is optional. If no value is given, then
it defaults to the standard Cursor class. If more control is required, then custom Cursor class can be
provided. To obtain a cursor object the statement would be:
cursor= db.cursor()
Once the above statement is executed, the cursor variable would have a cursor object.
import mysql.connector
mydb = mysql.connector.connect(host="localhost",user="root",passwd="",database="student")
mycursor = mydb.cursor()
mycursor.executemany(sql,val)
mydb.commit()
myresult = mycursor.fetchall()
for x in myresult:
print(x)
Note that you have to call the commit()on the connection object method explicitly in order to make the
changes to the database. You could also roll back using the rollback() method.
import mysql.connector
con=mysql.connector.connect(host="localhost",user="root",passwd="")
print(con)
mc=con.cursor()
mc.execute("SHOW DATABASES")
for u in mc:
print(u)
mc.execute("CREATE DATABASE PRODUCT")
import mysql.connector
con=mysql.connector.connect(host="localhost",database="PRODUCT1",user="root",passwd="")
mc=con.cursor()
mc.execute("CREATE TABLE PRODUCT_DETAILS(PRODID INT,PRODNAME
VARCHAR(255),PRICE INT)")
sql="INSERT INTO PRODUCT_DETAILS(PRODID,PRODNAME,PRICE) VALUES(%s,%s,%s)"
val=[(111,"Printer",8000),(112,"Scanner",10000),(113,"PenDrive",600),(114,"KeyBoard",1500)]
mc.executemany(sql,val)
con.commit()
mc.execute("SELECT * FROM PRODUCT_DETAILS")
result=mc.fetchall()
for x in result:
print(x)
Import mysql.connector
try:
con=mysql.connector.connect(host="localhost",database="student",user="root",passwd="")
cursor=con.cursor()
val=(400,)
cursor.execute(query,val)
records=cursor.fetchall()
print("Name:",row[0])
print("RollNo:",row[1])
print("Class:",row[2])
print("Marks:",row[3])
sql_update_query = """Update details set Class = 'SY BSc' where RollNo = %s"""
val=(811,)
cursor.execute(sql_update_query,val)
con.commit()
except Error as e :
finally:
if(con.is_connected()):
con.close()
The primary socket API functions and methods in this module are:
socket()
bind()
listen()
accept()
connect()
connect_ex()
send()
recv()
close()
Python provides a convenient and consistent API that maps directly to these system calls, their C
counterparts. As part of its standard library, Python also has classes that make using these low-level socket
functions easier.
TCP Sockets
As you’ll see shortly, we’ll create a socket object using socket.socket() and specify the socket type
as socket.SOCK_STREAM. When you do that, the default protocol that’s used is the Transmission
Control Protocol (TCP). This is a good default and probably what you want.
Why should you use TCP? The Transmission Control Protocol (TCP):
Is reliable: packets dropped in the network are detected and retransmitted by the sender.
Has in-order data delivery: data is read by your application in the order it was written by the sender.
In contrast, User Datagram Protocol (UDP) sockets created with socket.SOCK_DGRAM aren’t reliable,
and data read by the receiver can be out-of-order from the sender’s writes.
In the diagram below, let’s look at the sequence of socket API calls and data flow for TCP:
Starting in the top left-hand column, note the API calls the server makes to setup a “listening” socket:
socket()
bind()
listen()
accept()
A listening socket does just what it sounds like. It listens for connections from clients. When a client
connects, the server calls accept() to accept, or complete, the connection.
The client calls connect() to establish a connection to the server and initiate the three-way handshake. The
handshake step is important since it ensures that each side of the connection is reachable in the network, in
other words that the client can reach the server and vice-versa. It may be that only one host, client or
server, can reach the other.
In the middle is the round-trip section, where data is exchanged between the client and server using calls
to send() and recv().
At the bottom, the client and server close() their respective sockets.
Communication Breakdown
Let’s take a closer look at how the client and server communicated with each other:
When using the loopback interface (IPv4 address 127.0.0.1 or IPv6 address ::1), data never leaves the host
or touches the external network. In the diagram above, the loopback interface is contained inside the host.
This represents the internal nature of the loopback interface and that connections and data that transit it are
local to the host. This is why you’ll also hear the loopback interface and IP
address 127.0.0.1 or ::1 referred to as “localhost”.
sock.bind( (adrs,
port) ) Bind the socket to the address and port
sock.send( data[,
flags] ) Send the data through the socket
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()# when a client makes a connection request
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
Client
import socket
The arguments passed to socket() specify the address family and socket type. AF_INET is
the Internet address family for IPv4. SOCK_STREAM is the socket type for TCP, the protocol
that will be used to transport our messages in the network.
Python comes with the built-in smtplib module for sending emails using the Simple Mail Transfer
Protocol (SMTP). smtplib uses the RFC 821 protocol for SMTP.We will use the Gmail SMTP server to
send emails, but the same principles apply to other email services.
If you decide to use a Gmail account to send your emails, it is recommended of setting up a throwaway
account for the development of your code. This is because you’ll have to adjust your Gmail account’s
security settings to allow access from your Python code, and because there’s a chance you might
accidentally expose your login details. To set up a Gmail address for testing your code, do the following:
There are two ways to start a secure connection with your email server:
• Start an SMTP connection that is secured from the beginning using SMTP_SSL().
• Start an unsecured SMTP connection that can then be encrypted using .starttls().
In both instances, Gmail will encrypt emails using TLS, as this is the more secure successor of SSL. As
per Python’s Security considerations, it is highly recommended that you use create_default_context() from
the ssl module. This will load the system’s trusted CA certificates, enable host name checking and
certificate validation, and try to choose reasonably secure protocol and cipher settings.
If you want to check the encryption for an email in your Gmail inbox, go to More→ Show original to see
the encryption type listed under the Received header.
smtplib is Python’s built-in module for sending emails to any Internet machine with an SMTP or ESMTP
listener daemon.
We will see how to use SMTP_SSL() first, as it instantiates a connection that is secure from the outset and
is slightly more concise than the .starttls()alternative. Keep in mind that Gmail requires that you connect
to port 465 if using SMTP_SSL(), and to port 587 when using .starttls().
Using SMTP_SSL()
The code example below creates a secure connection with Gmail’s SMTP server, using
the SMTP_SSL() of smtplib to initiate a TLS-encrypted connection. The default context of ssl validates
the host name and its certificates and optimizes the security of the connection
Using with smtplib.SMTP_SSL() as server: makes sure that the connection is automatically closed at the
end of the indented code block. If port is zero, or not specified, .SMTP_SSL() will use the standard port
for SMTP over SSL (port 465).
It’s not safe practice to store your email password in your code, especially if you intend to share it with
others. Instead, let the user type in their password when running the script
def onclick():
smtp_server = "smtp.gmail.com"
msg=EmailMessage()
msg['From'] =sender_email.get()
msg['To'] = receiver_email.get()
context = ssl.create_default_context()
server.login(sender_email.get(), password.get())
server.sendmail(sender_email.get(),receiver_email.get(),msg.as_string())
root=Tk()
password=StringVar()
sender_email=StringVar()
receiver_email=StringVar()
msg=StringVar()
senderentry=Entry(root,textvariable=sender_email).grid(column=1,row=0)
l2=Label(root, text="Password").grid(column=0,row=1)
passentry=Entry(root,textvariable=password,show="*").grid(column=1,row=1)
receiverentry=Entry(root,textvariable=receiver_email).grid(column=1,row=2)
l4=Label(root, text="Message").grid(column=0,row=3)
msgentry=Entry(root,textvariable=msg).grid(column=1,row=3)
btn=Button(root,text="SEND",command=onclick).grid(column=0,row=4)
root.mainloop()