Python MySQL
w3school.com MySQL 8.0 Reference Manual
Introduction Python can be used in database applications.
One of the most popular databases is MySQL.
MySQL Database
To be able to experiment with the code examples in this tutorial, you should have MySQL installed on your computer.
Download MySQL Server from Homebrew
OR Download MySQL Server from MySQL Official Website
Install MySQL Driver
Python needs a MySQL driver to access the MySQL database.
In this tutorial we will use the driver “MySQL Connector”.
I recommend PIP or Conda to install “MySQL Connector”.
PIP is most likely already installed in your Python environment.
If you never heard PIP, click here
Navigate your command line to the location of PIP, and type the following:
Install mysql-connector-python
. DO NOT install mysql-connector
:
Shell 1 2 3 4 5 conda install mysql-connector-python python3 -m pip install mysql-connector-python
Now you have downloaded and installed a MySQL driver.
Test MySQL Connector To test if the installation was successful, or if you already have “MySQL Connector” installed, create a Python page with the following content:
Python
if this page is executed with no errors, you have the mysql.connector
module installed.
Create Connection Start by creating a connection to the database.
Use the username and password from your MySQL database:
Python 1 2 3 4 5 6 7 8 import mysql.connectormysql_connect = mysql.connector.connect( host = "localhost" , user = "your_username" , passwd = "your_password" , database = "your_database" )
Now you can start querying the database using SQL statements.
Test Connection Python 1 2 mysql_connect.is_connected()
MySQL Create User
https://dev.mysql.com/doc/refman/8.0/en/create-user.html
Official Statement: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 CREATE USER [IF NOT EXISTS ] user [auth_option] [, user [auth_option]] ... DEFAULT ROLE role [, role ] ... [REQUIRE {NONE | tls_option [[AND ] tls_option] ...}] [WITH resource_option [resource_option] ...] [password_option | lock_option] ... user : (see Section 6.2 .4 , “Specifying Account Names”) auth_option: { IDENTIFIED BY 'auth_string' | IDENTIFIED BY RANDOM PASSWORD | IDENTIFIED WITH auth_plugin | IDENTIFIED WITH auth_plugin BY 'auth_string' | IDENTIFIED WITH auth_plugin BY RANDOM PASSWORD | IDENTIFIED WITH auth_plugin AS 'auth_string' } tls_option: { SSL | X509 | CIPHER 'cipher' | ISSUER 'issuer' | SUBJECT 'subject' } resource_option: { MAX_QUERIES_PER_HOUR count | MAX_UPDATES_PER_HOUR count | MAX_CONNECTIONS_PER_HOUR count | MAX_USER_CONNECTIONS count } password_option: { PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY ] | PASSWORD HISTORY {DEFAULT | N} | PASSWORD REUSE INTERVAL {DEFAULT | N DAY } | PASSWORD REQUIRE CURRENT [DEFAULT | OPTIONAL] | FAILED_LOGIN_ATTEMPTS N | PASSWORD_LOCK_TIME {N | UNBOUNDED} } lock_option: { ACCOUNT LOCK | ACCOUNT UNLOCK }
Log into MySQL as root user:
1 2 3 4 5 6 7 import mysql.connectormysql_root = mysql.connector.connect( host="localhost" , user="your_username" , passwd="your_password" )
Get the cursor:
1 root_cursor = mysql_root.cursor()
root_cursor = mysql_root.cursor()
Try to create a user named "test" with password "passwd": 1 2 3 4 root_cursor.execute("CREATE USER 'test'@'localhost' \ IDENTIFIED WITH caching_sha2_password BY 'passwd' \ PASSWORD EXPIRE INTERVAL 30 DAY \ FAILED_LOGIN_ATTEMPTS 3 PASSWORD_LOCK_TIME 2;" )
Give test user ALL privilege for all database. Notice it is NOT safe to grant a user all privilege. It is only for testing conveniently.If you do not know privilege in MySQL, click here
1 2 root_cursor.execute("GRANT ALL ON *.* TO 'test'@'localhost' WITH GRANT OPTION;" ) root_cursor.execute("FLUSH PRIVILEGE" )
Test 1 2 3 4 5 6 7 8 9 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" ) print (mysql_test)
MySQL Create Database Creating a Database Assume you have follow all steps above, you should have a administrator user named test
with password passwd
.
To create a database in MySQL, use the CREATE DATABASE
statement:
Create a database named "mydatabase": 1 2 3 4 5 6 7 8 9 10 11 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" ) test_cursor = mysql_test.cursor() test_cursor.execute("CREATE DATABASE mydatabase" )
Check if Database Exists You can check if a database exist by listing all databases in your system by using the SHOW DATABASES
statement:
Return a list of your system's databases: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" ) test_cursor = mysql_test.cursor() test_cursor.execute("SHOW DATABASES;" ) for i in test_cursor: print (i)
If you print your cursor, it only returns the last command.
Or you can try to access the database when making the connection:
Directly access mydatabase while your are logging in. 1 2 3 4 5 6 7 8 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="mydatabase" )
If the database does not exist, you will get an error.
MySQL Select Assume we have:
a user named test
with password passwd
a database named BOS311
located in the localhost
a table named test
saved in BOS311
.
Select From a Table To select from a table in MySQL, use the SELECT
statement:
Select all records from the "test" table, and display the result: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() test_cursor.execute("SELECT * FROM test" ) result = test_cursor.fetchall() type (result)type (result[0 ])result[0 ] for row in result: print (row)
Note: We use the fetchall()
method, which fetches all rows from the last executed statement.
Selecting Columns To select only some of the columns in a table, use the SELECT
statement followed by the column name(s):
Select only the reason and location_zipcode columns: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() test_cursor.execute("SELECT reason, location_zipcode FROM test" ) result = test_cursor.fetchall() type (result)type (result[0 ])result[0 ]
Using the fetchone() Method If you are only interested in one row, you can use the fetchone()
method.
The fetchone()
method will return the first row of the result:
Fetch only one row: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() test_cursor.execute("SELECT * FROM test" ) result = test_cursor.fetchone() print (result)
MySQL Where Assume we have:
a user named test
with password passwd
a database named BOS311
located in the localhost
a table named test
saved in BOS311
.
Select With a Filter When selecting records from a table, you can filter the selection by using the “WHERE” statement:
Select record(s) where the location_zipcode is '02199': 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() sql = "SELECT * FROM test WHERE location_zipcode='02199'" test_cursor.execute(sql) result = test_cursor.fetchall() for row in result: print (row)
Wildcard Characters You can also select the records that starts, includes, or ends with a given letter or phrase.
Use the %
to represent wildcard characters:
Select records where the location contains the word 'Huntington Ave': 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() sql = "SELECT * FROM test WHERE location like '%Huntington Ave%'" test_cursor.execute(sql) result = test_cursor.fetchall() for row in result: print (row)
Prevent SQL Injection When query values are provided by the user, you should escape the values.
This is to prevent SQL injections, which is a common web hacking technique to destroy or misuse your database.
The mysql.connector module has methods to escape query values:
Escape query values by using the placholder %s
method:
Query data from a variable: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() sql = "SELECT * FROM test WHERE location_zipcode = %s" zip = ("02199" , )test_cursor.execute(sql, zip ) result = test_cursor.fetchall() len (result)
Query data from more variables: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import mysql.connectormysql_test = mysql.connector.connect( host="localhost" , user="test" , passwd="passwd" , database="BOS311" ) test_cursor = mysql_test.cursor() zip1 = "02199" zip2 = "02203" sql = "SELECT * FROM test WHERE location_zipcode = '{0}' OR location_zipcode = '{1}'" .format (zip1, zip2) test_cursor.execute(sql) result = test_cursor.fetchall() len (result)print (sql)
MySQL Update Update Table You can update existing records in a table by using the “UPDATE” statement:
Overwrite the priority
column from 2 to 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 import mysql.connectordef mysql_login (mysql_host, mysql_user, mysql_passwd, mysql_database ): global mysql_connect mysql_connect = mysql.connector.connect( host = mysql_host, user = mysql_user, passwd = mysql_passwd, database = mysql_database ) mysql_login( mysql_host = "localhost" , mysql_user = "test" , mysql_passwd = "passwd" , mysql_database = "BOS311" ) mysql = mysql_connect.cursor() mysql_table = "test_2020" case_information = {} case_information['priority' ] = 1 case_information['case_status' ] = 'Open' case_information['reason' ] = 'Street Lights' case_information['location' ] = '15 Sudbury St Boston MA 02203' def mysql_raise_priority (): sql = "UPDATE {0} SET priority = {1} WHERE case_status = '{2}' AND reason = '{3}' AND location = '{4}'" .format ( mysql_table, case_information['priority' ], case_information['case_status' ], case_information['reason' ], case_information['location' ] ) mysql.execute(sql) mysql_connect.commit() print (mysql.rowcount, "record(s) affected" ) mysql_raise_priority()
Important!: Notice the statement: mysql.connector.connect().commit()
. It is required to make the changes, otherwise no changes are made to the table.
Notice the WHERE clause in the UPDATE syntax : The WHERE clause specifies which record or records that should be updated. If you omit the WHERE clause, all records will be updated!
Prevent SQL Injection It is considered a good practice to escape the values of any query, also in update statements.
This is to prevent SQL injections, which is a common web hacking technique to destroy or misuse your database.
The mysql.connector module uses the placeholder %s
to escape values in the delete statement:
Escape values by using the placholder %s
method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import mysql.connectormydb = mysql.connector.connect( host="localhost" , user="yourusername" , passwd="yourpassword" , database="mydatabase" ) mycursor = mydb.cursor() sql = "UPDATE customers SET address = %s WHERE address = %s" val = ("Valley 345" , "Canyon 123" ) mycursor.execute(sql, val) mydb.commit() print (mycursor.rowcount, "record(s) affected" )
One More Thing Python Algorithms - Words: 2,640
Python Crawler - Words: 1,663
Python Data Science - Words: 4,551
Python Django - Words: 2,409
Python File Handling - Words: 1,533
Python Flask - Words: 874
Python LeetCode - Words: 9
Python Machine Learning - Words: 5,532
Python MongoDB - Words: 32
Python MySQL - Words: 1,655
Python OS - Words: 707
Python plotly - Words: 6,649
Python Quantitative Trading - Words: 353
Python Tutorial - Words: 25,451
Python Unit Testing - Words: 68