SQL Transactions in a Flask CRUD Application
When administering a database, DBAs are responsible for a wide variety of tasks. When performing them, they face all kinds of problems related to their database instances regarding performance, availability, and security. Those problems and changes within our database infrastructure are tracked thanks to transactions.
In this tutorial, I will discuss how to execute SQL transactions in a Flask application to achieve CRUD (Create, Read, Update, Delete) functionalities. To visualize our application’s database tables, I will be using DbVisualizer. DbVisualizer is a feature-rich, user-friendly multi-database solution for developers and database administrators that offers a single powerful interface across several operating systems. We will cover how to configure transaction operations using DbVisualizer.
Prerequisites
To follow this tutorial, you will need the following:
- Flask
- Python 3.*+
- DbVisualizer
Setting up the Flask Application
In this section, we will talk about building the UI of a contact manager application and its backend CRUD functions. Let’s start by building the user interface of our Flask application.
Building the User Interface
The UI of this application will allow us to showcase CRUD functionalities in our Flask application. Create a new folder to house your Flask project. In this folder, create another folder named “templates.” In the templates folder, create a new HTML file named “index.html” and copy the HTML code below into it.
In the code above, we created a list element to display all contacts in the database. We also created two forms that send data using the POST method. One collects data from users in input fields to create a contact, and the other collects the name of the contact to be deleted.
Building the Backend
Great! Our UI is now ready.
Let’s write the Flask backend that will receive data from it. Before we jump straight to the code, we will need to install a few libraries by running the commands below in your terminal.
Also, we will need to create a MySQL database for our application using phpMyAdmin - The query command; CREATE DATABASE [IF NOT EXISTS] db_name should do (replace db_name with your database name). You can also achieve it using DbVisualizer by creating a connection to your database server, as seen in this guide. After establishing a connection, navigate to the “Database” tab, right-click on “Databases” in the connections dropdown, and select “Create databases,” as shown in the image below:
Navigating the database connections dropdown
->
↑ Navigating the database connections dropdown
Finally, enter a name for your database and click on “Execute,” as shown in the image below:
Executing the database creation
->
↑ Executing the database creation
Now, with the libraries and database creation out of the way, let’s get to writing the backend for our application.
Create a python application in your Flask project named “app.py” and paste the python code below:
In the code above, we created a database connection to our SQL database called “ContactManager” and provided its credentials. Next, we created a table called “contacts” and provided a name and phone number column for it by executing the SQL query. We also made sure to catch the query using a try-except to avoid duplicate contact in the database.
Next, we need to create a function and URL to handle requests to the “index.html” page we created earlier. Copy the code below and paste it into the app.py file:
In the code above, we created a function called ”form” and linked it to the root URL for our application allowing it to receive both POST and GET requests using the @app.route() method. Next, we focused on implementing the CRUD functionalities:
For the create functionality, we achieved it by collecting the data received from the create a contact form on the Html page. We used this to execute an SQL INSERT query by passing it as the values required in the `contacts` table.
If you are looking for an easy and powerful SQL client and database manager, then you've got to try DbVisualizer. It connects to nearly any database.
The delete functionality was built by receiving a delete request from the Html page, then collecting the data for the item to be deleted in the POST request, and finally using it in the WHERE parameters when executing the SQL DELETE query.
The Update functionality was quite straightforward. We achieved it by checking if the item received from the create a contact form in the Html page already exists by executing the SQL SELECT query using the item name as an identifier in the WHERE clause. If the item existed already, we ran an SQL UPDATE query on the item setting the contact phone to the new value provided.
Finally, for the read functionality, we achieved everything by running a SQL SELECT query to retrieve all contacts in our database, then passed all the data to our `index.html` template.
After that, we can run the application using the following command:
With all these functionalities in place, you should have an application like the one in the GIF below:
Testing the Flask application’s CRUD functionalities
->
↑ Testing the Flask application’s CRUD functionalities
Transactions in the Flask Application
This section will cover adding SQL transactions to the queries in our Python CRUD functions and testing the different transaction commands. The transaction commands are:
- COMMIT:
The transactional command `COMMIT` is used to save all database changes made earlier by a transaction. This command saves all of the modifications made since the last commit or rollback. You can commit with either raw SQL queries or the `.commit()` method of your database instance. You can find an example in our `app.py` file just before the return statement, where we committed all changes that took place when we ran the function. - ROLLBACK:
The transaction command `ROLLBACK` is used to erase or undo all previously made database modifications. All modifications made since the last commit or rollback command are undone with this command. You can also use a `.rollback()` method of the db instance to call it in python as opposed to running raw SQL queries. Suppose we had to ping an online endpoint each time we wanted to delete a contact from our database. If that’s the case, we need to catch connection errors to this endpoint due to network issues or unavailability of the endpoint service and rollback database changes that occurred during the error. See the implementation below:
In the gif below, we provide you with the result of the `ROLLBACK` command:
Testing the ROLLBACK implementation
->
↑ Testing the ROLLBACK implementation
- SAVEPOINT:
The `SAVEPOINT` command establishes a point in the transaction at which all previous modifications are stored. A `SAVEPOINT` command can be issued solely for modifications made since the last save point. This command is useful when you wish to undo modifications and go back in time to a certain transaction. A good use case for our database is when we don’t want to commit any permanent changes to our database in case of an error and easily roll back to the initial point. If the process is without error, we can finally commit the previously made changes to our database. You can find the python implementation below:
In the code above when a user enters a contact, the phone number is updated to different values for each savepoint until it is finally committed permanently. However, if there is a connection error, the value is rolled back to a savepoint of our choice. In this case, it’s the first savepoint. The result of the code looks like this:
Testing the SAVEPOINT implementation
->
↑ Testing the SAVEPOINT implementation
- RELEASE SAVEPOINT:
To erase a previously generated SAVEPOINT, use the RELEASE SAVEPOINT command. Once a SAVEPOINT has been released, we can no longer use the ROLLBACK command to reverse transactions that have happened since the last SAVEPOINT.
Setting Transaction Modes In DbVisualizer
In this section, we will learn about different transaction modes in SQL and how to set them using DbVisualizer.
The AUTOCOMMIT Mode
MySQL's auto-commit feature is enabled by default. When the auto-commit mode is enabled, each SQL statement is evaluated as a transaction, and the outcome determines whether the statement is committed or rolled back. Successful statements are committed, whereas failing statements are immediately rolled back. Run the SQL command to manually disable auto-commit mode:
If you use DbVisualizer, keep in mind that on the transactions page, you will be able to toggle the auto-commit settings and save it by clicking on apply, alternatively, you can also use DbVisualizer to automatically set the autocommit mode by following this guide:
Setting the autocommit mode in DbVisualizer
->
↑ Setting the autocommit mode in DbVisualizer
Conclusion
This blog has shown you how to develop a Flask application and implement transactions in it - transactions will always help you to manage errors that could arise when database operations are running. Feel free to reach out to me on LinkedIn if you have any questions - other than that, learn about the plethora of features available in DbVisualizer from the documentation over here, and you should be good to go.