In Python 3, we can use the third-party library mysqlclient or pymysql to connect to the MySQL database and do data persistence operations. The usage of the two is exactly the same, only the imported module name is different. We recommend everyone use the pure Python third-party library pymysql, because it is easier to install successfully.
Below, we still use the hrs database created earlier as an example, to show how to use a Python program to operate the MySQL database and do data persistence operations.
First, we can install pymysql with the command below in the command line or in PyCharm's terminal. If you need to connect to MySQL 8, you also need to install a third-party library named cryptography to support the MySQL 8 password authentication method.
pip install pymysql cryptographyThe steps for using pymysql to operate MySQL are shown below:
- Create a connection. After the MySQL server starts, it provides a network service based on TCP, the Transmission Control Protocol. We can connect to the MySQL server through the
connectfunction of thepymysqlmodule. When calling theconnectfunction, we need to specify parameters such as host (host), port (port), username (user), password (password), database (database), and character set (charset). This function returns aConnectionobject. - Get a cursor. After successfully connecting to the MySQL server, the next thing to do is send SQL statements to the database server. MySQL will execute the received SQL and return the execution result through the network. To do this, we first need to get a cursor, that is, a
Cursorobject, through thecursormethod of the connection object. - Send SQL. Through the
executemethod of the cursor object, we can send SQL statements to the database. - If an
insert,delete, orupdateoperation is executed, we need to commit or roll back the transaction according to the actual situation. Because when the connection is created, the transaction environment is turned on by default. After the operation is completed, we need to use thecommitorrollbackmethod of the connection object to commit or roll back the transaction. Therollbackmethod is usually put in the exception handling blockexcept. If aselectoperation is executed, we need to fetch the query result through the cursor object. There are three methods for this:fetchone,fetchmany, andfetchall. Among them,fetchonefetches one record and returns it as a tuple or dictionary;fetchmanyandfetchallfetch multiple records and return them as nested tuples or a list of dictionaries. - Close the connection. After finishing the persistence operation, please do not forget to close the connection and release external resources. We usually use the
closemethod of the connection object in thefinallyblock to close the connection.
Below, we will use actual code to demonstrate the five steps above.
import pymysql
no = int(input('Department ID: '))
name = input('Department name: ')
location = input('Department location: ')
# 1. Create a connection
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4')
try:
# 2. Get a cursor
with conn.cursor() as cursor:
# 3. Execute SQL
affected_rows = cursor.execute(
'insert into `tb_dept` values (%s, %s, %s)',
(no, name, location)
)
if affected_rows == 1:
print('Department inserted successfully!')
# 4. Commit the transaction
conn.commit()
except pymysql.MySQLError as err:
conn.rollback()
print(type(err), err)
finally:
# 5. Close the connection
conn.close()Note:
127.0.0.1above is called the loopback address. It means the local machine. Theguestbelow is a user I created in advance. This user hasinsert,delete,update, andselectpermissions on thehrsdatabase. We do not recommend that everyone directly use therootsuper administrator account to access the database in a project. Doing that is really too dangerous.
Example SQL to create that user:
create user 'guest'@'%' identified by 'Guest.618';
grant insert, delete, update, select on `hrs`.* to 'guest'@'%';If you need to insert a large amount of data, it is recommended to use the executemany method of the cursor object to do batch processing, that is, one insert operation followed by many groups of data. Everyone can try inserting 10,000 records into a table, and then see the difference between inserting one by one without batch processing and inserting with batch processing. The first parameter of the executemany method is still an SQL statement, and the second parameter can be a list or tuple containing many groups of data.
import pymysql
no = int(input('Department ID: '))
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4',
autocommit=True)
try:
with conn.cursor() as cursor:
affected_rows = cursor.execute(
'delete from `tb_dept` where `dno`=%s',
(no, )
)
if affected_rows == 1:
print('Department deleted successfully!')
finally:
conn.close()Note: If you do not want to manually commit or roll back the transaction after every SQL operation, you can add a parameter named
autocommitin theconnectfunction and set it toTrue, which means after each SQL is executed successfully, it is committed automatically. But we recommend everyone commit or roll back manually, so that the transaction environment can be built according to the actual business needs. If you do not want to catch and handle exceptions, you can directly putfinallyafter thetryblock. Omittingexceptmeans that when an exception happens, the code will crash directly and show the exception stack in the terminal.
import pymysql
no = int(input('Department ID: '))
name = input('Department name: ')
location = input('Department location: ')
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4')
try:
with conn.cursor() as cursor:
affected_rows = cursor.execute(
'update `tb_dept` set `dname`=%s, `dloc`=%s where `dno`=%s',
(name, location, no)
)
if affected_rows == 1:
print('Department updated successfully!')
conn.commit()
except pymysql.MySQLError as err:
conn.rollback()
print(type(err), err)
finally:
conn.close()- Query the department table:
import pymysql
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4')
try:
with conn.cursor() as cursor:
cursor.execute('select `dno`, `dname`, `dloc` from `tb_dept`')
row = cursor.fetchone()
while row:
print(row)
row = cursor.fetchone()
except pymysql.MySQLError as err:
print(type(err), err)
finally:
conn.close()Note: In the code above, we use a
whileloop to fetch the query result row by row. This way is especially suitable when the query result has a very large number of rows. Because iffetchallis used to fetch all records into a nested tuple at one time, it will cause very large memory overhead, and in many scenarios this is not a good idea. If you do not want to use awhileloop, you can also think about using theiterfunction to build an iterator and fetch data row by row. Interested readers can study it by themselves.
- Paginated query on the employee table:
import pymysql
page = int(input('Page: '))
size = int(input('Page size: '))
con = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8')
try:
with con.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute(
'select `eno`, `ename`, `job`, `sal` from `tb_emp` order by `sal` desc limit %s,%s',
((page - 1) * size, size)
)
for emp_dict in cursor.fetchall():
print(emp_dict)
finally:
con.close()Below we explain an example of exporting database table data to an Excel file. We first need to install the third-party library openpyxl. The command is shown below.
pip install openpyxlNext, through the code below, we export all employees' ID, name, job, monthly salary, allowance, and department name from the hrs database to an Excel file.
import openpyxl
import pymysql
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = 'Employee Basic Info'
sheet.append(('Employee ID', 'Name', 'Job', 'Salary', 'Allowance', 'Department'))
conn = pymysql.connect(host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4')
try:
with conn.cursor() as cursor:
cursor.execute(
'select `eno`, `ename`, `job`, `sal`, coalesce(`comm`, 0), `dname` '
'from `tb_emp` natural join `tb_dept`'
)
row = cursor.fetchone()
while row:
sheet.append(row)
row = cursor.fetchone()
workbook.save('hrs.xlsx')
except pymysql.MySQLError as err:
print(err)
finally:
conn.close()You can refer to the example above and try importing the data in an Excel file into the specified table of the specified database, and see whether it can be done successfully.