
Introduction
Python is a high-level programming language that allows you to create highly available applications with support for popular relational database systems such as MySQL. To permanently store data records and interact with databases, you can use a RCS Managed Database for MySQL with Python to improve your application structure and availability.
This guide explains how to use a RCS Managed Database for MySQL with Python. You are to create a sample application that uses the Python MySQL connector to query user data and interact with the database tables.
Prerequisites
Before you begin:
Deploy a RCS Managed Database for MySQL
Install the MySQL client tool on your development machine
Depending on your computer operating system, use a package manager such as
brewon macOS,apton Ubuntu/Debian systems,dnfon RHEL systems, among others to install the MySQL client tool. For example, on Ubuntu, run the following command:$ sudo apt install mysqlUpdate the Python Pip package manager
$ pip install --upgrade pip
Set Up the Database
To interact with your RCS Managed Database for MySQL, install the Python mysql-connector-python driver and set up the database as described in the steps below.
Using
pip, install the Python MySQL driver$ pip install mysql-connector-pythonUsing the MySQL client tool, connect to your RCS Managed Database for MySQL
$ mysql -h prod-db.RCSdb.com -P 16751 -u RCSadmin -pReplace the above values with your actual RCS Managed Database for MySQL details:
Host:
prod-db.RCSdb.comUsername:
RCSadminPort:
16751
When prompted, enter your Database password and press ENTER to access the console.
Create a sample
company_portaldatabasemysql> CREATE DATABASE company_portal;Create a new database user
app_userwith a strong passwordmysql> CREATE USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'strong-password';Grant the user full privileges to the
company_portaldatabasemysql> GRANT ALL PRIVILEGES ON company_portal.* TO 'app_user'@'%';Refresh the MySQL privileges
mysql> FLUSH PRIVILEGES;Switch to the
company_portaldatabasemysql> USE company_portal;Create a sample
productstable with three columnsmysql> CREATE TABLE products ( product_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, product_name VARCHAR(50), retail_price DOUBLE ) ENGINE = InnoDB;In the above table, the
AUTO_INCREMENTvalue on theproduct_idcolumn assigns uniqueproduct_idsfor new records.Add sample data to the
productstablemysql> INSERT INTO products (product_name, retail_price) VALUES ('8GB MEMORY CARD', 6.95); INSERT INTO products (product_name, retail_price) VALUES ('2TB SSD', 300); INSERT INTO products (product_name, retail_price) VALUES ('WI-FI DONGLE', 14.50);View the
productstable datamysql> SELECT product_id, product_name, retail_price FROM products;Output:
+------------+-----------------+--------------+ | product_id | product_name | retail_price | +------------+-----------------+--------------+ | 1 | 8GB MEMORY CARD | 6.95 | | 2 | 2TB SSD | 300 | | 3 | WI-FI DONGLE | 14.5 | +------------+-----------------+--------------+ 3 rows in set (0.00 sec)Exit the MySQL console
mysql> QUIT;
You have set up a MySQL database, a products table, and added sample table data to use in your Python application. You can add multiple columns and records to match your application structure.
Create the Python Application
Data-driven applications use Create, Read, Update, and Delete (CRUD) operations to handle user interactions. Set up a Python application that performs these CRUD operations with the following parts:
A User Interface (UI)
An Application Programming Interface (API). The user interface communicates to the API that uses the following HTTP methods to translate requests to CRUD operations
POST: Creates a new resource in the applicationGET: Retrieves the application resourcesPUT: Updates the details of an existing resourceDELETE: Removes a resource from the application.
Based on the above structure, create a Python API application that accepts HTTP requests to interact with the MySQL database.
Create the Python MySQL Module
Create a new
projectdirectory$ mkdir projectSwitch to the directory
$ cd projectUsing a text editor such as
nano, create a newmysql_gateway.pyfile$ nano mysql_gateway.pyAdd the following contents to the file. Replace the
host,password, andportvalues with your actual RCS Managed Database for MySQL detailsimport mysql.connector class MysqlGateway: def __init__(self): self.last_row_id = 0 def db_conn(self): mysql_con = mysql.connector.connect( host = "prod-db.RCSdb.com", user = "app_user", password = "strong-password", database = "company_portal", port = "16751" ) return mysql_con def query(self, query_string, resource_id = ""): mysql_con = self.db_conn() db_cursor = mysql_con.cursor(dictionary = True) if resource_id == "": db_cursor.execute(query_string) else: db_cursor.execute(query_string, (resource_id,)) return db_cursor.fetchall() def execute(self, query_string, data): mysql_con = self.db_conn() db_cursor = mysql_con.cursor(dictionary = True) db_cursor.execute(query_string, data) mysql_con.commit() self.last_row_id = db_cursor.lastrowidSave and close the file.
In the above application:
import mysql.connectorimports the MySQL connector for Python to your applicationThe
MysqlGatewayclass defines the following methods:__init__(self)executes every time you create a new instance of theMysqlGatewayclass and initializes thelast_row_idvariable to0db_conn(self)connects to the managed database and returns a reusable connection using thereturn mysql_constatementquery(self, query_string, resource_id = "")runs theSELECTSQL command and returns results from the database table as a dictionary with the column names and valuesexecute(self, query_string, data)runs theINSERT,UPDATE, andDELETEoperations and returns thelastrowidwhen you insert a new record
Create the Products Resource Module
In the sample application database, you have a single products table. A mission critical-application can have hundreds of tables such as payment_methods, banks, customers, sales, and inventories. To organize your application data, create a resource module for every table. In this section, create the products resource module as described below.
Create a new
products.pyfile$ nano products.pyAdd the following contents to the file
class Products: def __init__(self, mysql_gateway): self.dg = mysql_gateway def create(self, json_data): sql_query = "insert into products (product_name, retail_price) values (%s, %s)" self.dg.execute(sql_query, (json_data["product_name"], json_data["retail_price"])) return self.read(self.dg.last_row_id) def read(self, resource_id = ""): if resource_id == "" : sql_query = "select * from products" else: sql_query = "select * from products where product_id = %s" resp = self.dg.query(sql_query, resource_id) return resp def update(self, json_data, resource_id): sql_query = "update products set product_name = %s, retail_price = %s where product_id = %s" self.dg.execute(sql_query, (json_data["product_name"], json_data["retail_price"], resource_id)) return self.read(resource_id) def delete(self, resource_id): sql_query = "delete from products where product_id = %s" self.dg.execute(sql_query, (resource_id,)) return "Success"Save and close the file
In the above module, the
Productsclass has the following methods:__init__(self, mysql_gateway)runs when you call the module for the first time. The method takes themysql_gatewayclass instance as an argument to connect to the database for each CRUD operationcreate(self, json_data)accepts data in JSON format and uses theinsert into products (product_name, retail_price) values (%s, %s)SQL statement to insert the data to theproductstable by executing theself.dg.execute(...)from themysql_gatewaymoduleread(self, resource_id = "")runs theselect * from productsorselect * from products where product_id = %sSQL statements to either return all products or a single product.update(self, json_data, resource_id)runs theupdate products set product_name = %s, retail_price = %s where product_id = %sSQL command to update a product that matches theproduct_iddelete(self, resource_id)deletes a product that matches the givenresource_idusing thedelete from products where product_id = %sSQL command
Create the main Application Entry Point
To use the database structure that includes a MySQL gateway class and products module, create the application's main function that executes when you run the application as described below.
Create a new
index.pyfile$ nano index.pyAdd the following contents to the file
import http.server from http import HTTPStatus import socketserver import json import mysql_gateway import products class WebServerHandler(http.server.SimpleHTTPRequestHandler): def init_db(self): self.db_gateway = mysql_gateway.MysqlGateway() def write_http_output(self, resp): self.send_response(HTTPStatus.OK) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(bytes(json.dumps(resp, indent = 2) + "\r\n", "utf8")) def do_POST(self): self.init_db() json_data = json.loads(self.rfile.read(int(self.headers['Content-Length']))) http_resource = products.Products(self.db_gateway) self.write_http_output({"data": http_resource.create(json_data)}) def do_GET(self): self.init_db() http_resource = products.Products(self.db_gateway) resource_id = "" if len(self.path.split("/")) >= 3: resource_id = self.path.split("/")[2] self.write_http_output({"data": http_resource.read(resource_id)}) def do_PUT(self): self.init_db() json_data = json.loads(self.rfile.read(int(self.headers['Content-Length']))) resource_id = "" if len(self.path.split("/")) >= 3: resource_id = self.path.split("/")[2] http_resource = products.Products(self.db_gateway) self.write_http_output({"data": http_resource.update(json_data, resource_id)}) def do_DELETE(self): self.init_db() resource_id = "" if len(self.path.split("/")) >= 3: resource_id = self.path.split("/")[2] http_resource = products.Products(self.db_gateway) self.write_http_output({"data": http_resource.delete(resource_id)}) httpd = socketserver.TCPServer(('', 8080), WebServerHandler) print("Web server started at port 8080...") try: httpd.serve_forever() except KeyboardInterrupt: httpd.server_close() print("Web server stopped.")Save and close the file
In the above application code:
The
importsection declares the necessary modules to offer HTTP functionalities and imports the custommysql_gatewayandproductsmodules you created earlierThe
WebServerHandler()is a handler class for the HTTP server. Within the class,init_db()invokes your custommysql_gatewaymodule. Then, thewrite_http_output(self, resp)method sets the correct HTTP response headers for the web application.The
do_POST(self),do_GET(self),do_PUT(self), anddo_DELETE(self)methods match each HTTP client request to the correct resource methodThe
httpddeclaration starts an HTTP server that listens for incoming requests on port8080and directs the requests to theWebServerHandler()class
Test the Application
List files in your working directory
$ lsOutput:
index.py mysql_gateway.py products.pyVerify that the
mysql_gateway.py,products.py, andindex.pyfiles are availableRun the Python application as a background process
$ python3 index.py &Output
Web server started at port 8080...Establish a new
SSHconnection in a new terminal window and execute the followingcurlcommands to test all CRUD operations:Using the
curlutility, test the following application CRUD operationsCreate a new product
$ curl -X POST http://localhost:8080/ -H 'Content-Type: application/json' -d '{"product_name": "WIRE STRIPPER", "retail_price": 15.28}'Output:
{ "data": [ { "product_id": 4, "product_name": "WIRE STRIPPER", "retail_price": 15.28 } ] }Retrieve all products in the database
$ curl -X GET http://localhost:8080/productsOutput:
{ "data": [ { "product_id": 1, "product_name": "8GB MEMORY CARD", "retail_price": 6.95 }, { "product_id": 2, "product_name": "2TB SSD", "retail_price": 300.0 }, { "product_id": 3, "product_name": "WI-FI DONGLE", "retail_price": 14.5 }, { "product_id": 4, "product_name": "WIRE STRIPPER", "retail_price": 15.28 } ] }Get a single product
$ curl -X GET http://localhost:8080/products/1Output:
{ "data": [ { "product_id": 1, "product_name": "8GB MEMORY CARD", "retail_price": 6.95 } ] }
Update product details. For example, the product ID
4$ curl -X PUT http://localhost:8080/products/4 -H 'Content-Type: application/json' -d '{"product_name": "WIRE STRIPPER", "retail_price": 23.50}'Output:
{ "data": [ { "product_id": 4, "product_name": "WIRE STRIPPER", "retail_price": 23.5 } ] }Delete a product
$ curl -X DELETE http://localhost:8080/products/2Output:
{ "data": "Success" }
Conclusion
You have used a RCS Managed Database for MySQL for Python by creating a sample CRUD operation application that allows you to create, update, and delete database records. By integrating a managed database, you can concentrate development efforts on the Python application to offer more features and handle user interactions.
Next Steps
To implement more solutions using your RCS Managed Database, visit the following resources: