Python: Converting SQL Data to JSON

Sql To Json Featured

In terms of managing databases, the market is ruled by two of the most in-demand technologies, which are SQL and JSON. Why is it necessary to transform some SQL data into JSON when both technologies are beneficial in their own ways and are fairly robust? Does this need to be completed? Is it possible to convert SQL Data to JSON using Python? If yes, then how?

All the above questions will be answered, as we will leave no stone unturned and study these concepts in this article.

Importance of Returning SQL data as JSON in Python

JSON is simple to understand, and it does not burden the machine because it is lightweight. As both machines and humans are able to understand it, it is gaining popularity. Hence, converting SQL to JSON will provide a structure or a format that is understandable by a large number of people and also parseable by most machines.

There are various other factors, such as JSON being frontend friendly and JSON allowing us to interchange data with Mobile apps, that make returning SQL data as JSON important.  Python is a tool used by a wide majority these days; we must learn to do the same using Python. 

Python’s Capabilities in Data Conversion

Python is a multi-purpose programming language that has a wide variety of libraries and packages that can help us do data conversion with ease.

To learn Python Programming please read along with this article.

Our lives as developers are made very easy as we are able to do data conversion operations on a wide range of data formats and structures. It is capable of performing operations on formats ranging from JSON to YAML, HTML to Binary data, and date-time formats to Numeric data types. Python’s excellent capabilities and the powerful libraries that it comes with have made it a go-to choice for analysis and data-handling tasks.

As we have gained some basic information about the need to convert SQL data into JSON and also brushed through why Python could be a tool that we can use for this purpose, going ahead in this article we will be understanding in depth various aspects, such as some important concepts about both SQL and JSON and the major differences between them.

Then we will start by creating our database and then performing the conversion from SQL to JSON, and later on we will also cover some other important points related to this topic. 

Understanding SQL and JSON

SQL and its Role in Data Storage

SQL is a short form for Structured Query Language. Handling relational databases is mostly done using it. It takes a structured approach, as implied by the name, and arranges the data in rows and columns.

Because of its integrity constraints, which guarantee the data’s accuracy and consistency, its ability to help us create relationships when working with relational data, and its adherence to the ACID (Atomicity, Consistency, Integrity, Durability) properties, SQL plays a crucial role in managing and storing data.

JSON and its Advantages in Data Interchange

JSON data interchange format is very lightweight and both humans and machines can work on it. A key-value pair structure is followed by it. It represents complex data very efficiently with the help of nested data hierarchies.

Working with a variety of programming languages and being simple to use, is being well-liked. It is helpful in data exchange since it is clear, simple to read and write, not restricted to any particular computer language, and ideal for usage in Web APIs because it is native to JavaScript.

SQL Vs JSON

SQL and JSON both have important roles in data interchange and management but have fairly different approaches and use cases. JSON format represents data in a hierarchical, nested fashion, whereas SQL databases store data in structured, tabular formats.

For querying and manipulating data in SQL databases, SQL commands are used JSON doesn’t have a query language; instead, it makes use of the data manipulation features of the hosting programming language. Contrary to JSON, which lacks built-in integrity capabilities, SQL databases enforce data integrity constraints. The application or platform employing JSON is what determines how data integrity is maintained.

Table and column structures must adhere to a strict schema that SQL databases impose. The lack of a schema in JSON, on the other hand, enables dynamic and flexible data representation. Since we have been going through all the theoretical concepts and gaining an understanding of the various points, let’s begin with actually writing some code and understanding the importance of converting SQL data to JSON in Python.

Setting Up the Environment

SQLite3 and its Relevance

Because it is open source, lightweight, and doesn’t need a dedicated server to function, SQLite3 is a very popular option because it makes running and deploying software very simple. Due to its excellent handling of tiny and medium-sized databases, it is the greatest option for lightweight prototypes and development.

SQLite3 does not require any external dependencies as it is a self-sufficient tool and does not require any configurations it is ready to use, it follows the ACID properties as well.

For getting a better understanding of the SQLite module you can read through this link.

Need of Specific Python Libraries for Data Conversion

Using specific libraries becomes necessary to use when it comes to performing complex operations even though Python is capable enough to do several things on its own.

Along with CSV, XML and YAML Python can handle a wide range of formats of data. Python can handle a wide range of data formats with libraries, including CSV, XML, and YAML.

Installation of the Required Libraries.

To start, your computer should have Python installed first.

If you don’t  have it installed yet, you should read the Python Tutorial article at the linked link.

Run the following command on your terminal to install SQLite3 if it hasn’t already been installed on your computer.

pip install pysqlite3

On successful execution, the above code will install SQLite3 in your machine making it ready and available to be imported.

Connecting Python to an SQL Database.

We’ve covered so much theory so far and it’s time that we get some hands-on experience and get a better understanding of how things happen.

Let’s just start by creating a very basic database using SQLite3 and Python.

Creating a Basic Database in SQLite3

To begin with I have created a ‘database.py’ in which I will be writing the code to create a database only, for good practice we will not be using this file for any other purpose. As of right now, we are only concerned with creating the database; later on in the post, we will discuss performing operations on the database that we established using a distinct Python file.

The picture below shows my directory structure:

Sql Directory Structure1
Directory Structure

Inside the ‘database.py’ I will be running the below code and then let’s see what happens next.

Below is an example of how a very basic database can be created, along with the code explanation. 

import sqlite3 as sql

conn = sql.connect('test_database.db')

cursor = conn.cursor()

cursor.execute('''
                CREATE TABLE IF NOT EXISTS cars(
                    car_id INTEGER PRIMARY KEY,
                    brand TEXT NOT NULL,
                    price INTEGER NOT NULL
                )''')

cursor.execute("INSERT INTO cars (brand, price) VALUES ('TATA', 300000)")
cursor.execute("INSERT INTO cars (brand, price) VALUES ('Mahindra', 2500000)")

conn.commit()

cursor.close()
conn.close()
Database Creation Example
Database Creation Example

To learn it in a better way and before moving on to the code explanation, it is advised that you learn some basics of SQLite3.

To learn more about SQLite3, please check out the linked page.

Coming back to the explanation, the above code is the simplest example of creating a database. Let’s go through it line by line, doing a complete autopsy of the code. In line one, there is nothing very complex; I have just imported SQLite3 as SQL so that I don’t have to type a long name every time. In line 3, I have created a variable named ‘conn, which is responsible for creating a connection from our Python file to the SQL database.

The ‘sql.connect()’ function takes a file name as the parameter and creates a connection with that file. If there is no file with the specified name, the function will create one, as in our case. You can see that a new database file is created with the name that I passed in the same directory because I did not explicitly mention a file path.

Sql Directory Structure2
Directory Structure with ‘test_database’

At this stage, we have created a database file called ‘test_database’.

On line 5, I have created a cursor that will be responsible for carrying out operations, or in other words, performing queries on our database.

Then on line 7, there is a general SQL query that creates a table in our database with the name ‘cars’, in which there are three columns ‘car_id’, ‘brand’ and ‘price’. All three of these cannot be empty as car_id is a primary key, and the other two are mentioned as ‘NOT NULL’. On lines 14 and 15 there are two example queries in which I have inserted some data into our newly created database.

Then, at 17, I committed our database. Until we commit our database, it won’t get into a stable state, so it is important to commit after we have finished our operations. Lastly, on lines 19 and 20, I have closed the cursor and the connection that we had created earlier in our code.

Establish a Connection with a Database

In this part, we will only look at connecting the database that we already generated to a Python file. I will try to connect our database to a new Python file I’ve created called “file1.py” for this purpose.

Sql Directory Structure3
Directory Structure with ‘file.py’

The below code will only create a connection with the ‘test_database’ file that we have already created and not perform any operations.

If there is difficulty understanding the code, please refer to the code explanation provided in the previous example.

import sqlite3

conn = sqlite3.connect('my_database.db')
if conn:
    print("Successfully Connected...")

cursor = conn.cursor()

cursor.close()
conn.close()

The above code will result in the output shown in the image below:

Sql Connection Successful Example
Sql Connection Successful

Authenticating and authorizing access

Unlike more complicated database systems, SQLite3 lacks integrated user management and authentication. Instead, file system permissions control who can access the database file.

You should configure the proper file system permissions to prohibit unauthorized database access.

If you require more sophisticated authentication and authorization tools, database systems that provide more extensive management, such as PostgreSQL or MySQL could be a better choice.

Working with SQL Database

Understanding and executing SQL queries using Python

For the example, I will be using the table that we have already created. I will be running these queries from the ‘file1.py’ that we have already connected with our database, and we will be using the knowledge that we have gained from the previous sections, so I would strongly recommend that you read the previous section before you jump to this one. 

Create Table

We have already taken a look at this query in the previous section, please check out that section for an example as well as a detailed code explanation.

Insert

This query is used to insert data into our newly created table. You can see how this works in the below example.

cursor.execute("INSERT INTO cars(brand, price) VALUES ('Toyota', 5000000)")

Select

The select query is used to select a specific value or even an entire row from our table to perform operations on that specific data.

cursor.execute("SELECT * FROM cars")

Delete

The delete query is used to delete a specific value from the table, it uses the ‘WHERE’  keyword as an identification criterion.

cursor.execute("DELETE FROM cars WHERE car_id = 2")

Retrieving Results from Executed Queries

We have performed various queries on our database, but we must find a way through which we can see what is happening to our database. For this purpose, we will be using the ‘fetchall()’ query.

Let’s understand this with the help of an example.

import sqlite3

conn = sqlite3.connect('test_database')
if conn:
    print("Successfully Connected...")

cursor = conn.cursor()

cursor.execute("SELECT * FROM cars")
print("Selection successfull...")

data = cursor.fetchall()
for values in data:
    print(values)

conn.commit()
cursor.close()
conn.close()
Sql Fetchall Example
Sql Fetchall Example

The above code shows how the fetchall() function works. The rest of the code is something that we are familiar with by now and does not require further explanations. What we are concerned with is what’s happening between lines 9 and 14. On line 9, we have executed the SELECT query that we saw above, and with the help of that, we have selected all the data from our table.

Then on line 12, we used the fetchall() keyword to store all the data selected by the SELECT query and store it in a variable named ‘data’. Lastly, on lines 13 and 14, we have just iterated through the data and printed it.

Converting SQL Data to JSON

Introduction to JSON module

The pre-installed Python library for working with JSON data is known as the json module. It enables you to deserialize JSON data back into Python objects and serialize Python objects (such as dictionaries and lists) into JSON format.

You must employ the json module in Python to convert SQL data to JSON.

Serialization and Deserialization

Python objects are transformed into JSON format by a process known as serialization, which makes them appropriate for transmission or storage.

On the other hand, deserialization entails processing JSON data into Python objects. For these operations, the json module offers two primary functions, which are ‘json.dumps(value)’ and ‘json.loads(json_string)’.

We will see how these functions are used in the following sections.

Converting SQL Query results to JSON format using Python

Let’s just directly see how things happen in action with the help of the following example:

import sqlite3
import json

conn = sqlite3.connect('test_database')
if conn:
    print("Successfully Connected...")

cursor = conn.cursor()

cursor.execute("SELECT * FROM cars")
print("Selection successfull...")

rows = cursor.fetchall()
columns = [col[0] for col in cursor.description]
data = [dict(zip(columns, row)) for row in rows]

to_json = json.dumps(data, indent=2)
print(to_json)

conn.commit()
cursor.close()
conn.close()
Sql To Json
Converting SQL To JSON

We are using the same database that we created earlier, and we will be using the same ‘file1.py’ file that we created earlier to establish a connection with our database. Everything remains the same; we have created the connection, created a cursor, and then selected all the data using the SELECT query.

What’s different in this example is that we have imported the ‘json’ module on line 2. Let’s jump to line 13′. On this line, I have stored all the data selected earlier into a ‘row’ variable, and then on line 14, I’ve created another variable called ‘column’, which will store the column names of our ‘cars’ table.

After that, I zipped the two arrays that we just created in such a way that the column names became keys and their corresponding row values became values for those keys, respectively. Finally, I printed the data in JSON format on line 17, using the serialization function of the json module to transform the previously produced data into that format.

The graphic below shows what the JSON format looks like:

Sql To Json Output
Sql To Json Output

In this way, you can easily convert your SQL data into JSON format using the above code.

Handling Complex Data Structures

Dealing with Nested Queries

Before serializing the nested data to JSON when your SQL results contain nested queries, you must convert the nested data into a suitable format.

To accomplish this, you can use nested loops and data manipulation.

Handling Relationships Between Tables

You must arrange the data properly when working with relationships between tables (such as one-to-many relationships) so that the JSON data accurately reflects these relationships.

Writing the JSON Data to a File

Let us figure out how we can write the JSON data that we just created to different types of files.

Plain Text File (.json)

The easiest selection is this one. The JSON data can be saved as plain text in a json file. This format is straightforward and practical for sharing.

It can be done using the below code:

with open('cars.json', 'w') as file:
    file.write(to_json)

Json To Text File
Json To Text File

Doing this will create a new ‘.json’ file in your current working directory.

Json To Text File Directory
Directory Structure

Compressed File (.json.gz)

You can use gzip or zip compression to reduce the size of the JSON file if you need to conserve disc space or send the JSON data over the internet. The file size is greatly reduced; however, viewing the contents requires decompression.

To use this method, first import ‘gzip’ using the below statement:

import gzip
with gzip.open('cars.json.gz', 'wb') as file:
    file.write(to_json.encode('utf-8'))
Json Compressed
Compressed JSON

Running the above code will create a new ‘.json.gz’ file in your current directory.

Json Compressed Directory
Directory Structure

Binary File (.jsonb)

You can think about saving the JSON data in binary format for performance and security reasons. This may be accomplished using the pickle package in Python.

with open('cars.jsonb', 'wb') as file:
    file.write(to_json.encode('utf-8'))
Json Binary
JSON to Binary

Running the above code will create a new ‘.jsonb’ file in your working directory.

Json Binary Directory
Directory Structure

Error Handling and Troubleshooting

Common issues with datatype and formatting while Conversion

When converting data from SQL to JSON in Python, common issues can arise, such as TypeErrors when working with non-serializable objects, ValueErrors from corrupted or malformed JSON data, KeyErrors from attempting to access keys that aren’t present in nested JSON, and IndentationErrors from improper code indentation.

For instance, a TypeError will be triggered if a datetime object is attempted to be serialized using json.dumps(). If there are more characters in the JSON data during deserialization, a ValueError will also be raised.

It is important to handle these concerns properly to transfer data without any problems and avoid crashes.

Techniques to identify and resolve errors

Effective techniques include the use of try-except blocks for handling exceptions, print statements or logging to output pertinent information and identify code flow, pprint to inspect complex data structures, debuggers like pdb or integrated IDEs for interactive debugging, and consulting official documentation and online resources for answers.

Applying a try-except block around json.dumps(), for instance, enables us to catch TypeErrors and gracefully manage them. Additionally, step-by-step examination is made possible by IDE debuggers and the use of pprint to visually check JSON data structures for faults. Python application’s data conversion becomes more stable and dependable when we combine these techniques.

Real-World Applications

Practical application of returning SQL data as JSON

Practical application of returning SQL data as JSON. Along with a wide range of real-world applications, a powerful method is returning SQL data as JSON

Building RESTful APIs, where JSON is a common data interchange format, is one such application. We can smoothly supply data to web and mobile applications through APIs by converting SQL query results to JSON format. The performance of the entire program is improved, and frontend-backend communication is promoted as this makes data transfer efficient.

Providing simple data transmission and interoperability across various platforms and computer languages, the simplicity of JSON also makes it a great choice for file configuration and data storage.

Use cases in various domains

There are many useful use cases where it is advantageous to return SQL data in JSON. In mobile and web applications, real-time data is allowed by JSON-formatted data through APIs. For the analysis of huge datasets, JSON data transfer is seamless. Sensor data is conveniently interpreted by IoT applications using JSON. Chatbots and configuration management both benefit from JSON.

In a dispersed system, it acts as a standard format for data exchange and allows for data sharing and integration. Data consumption is made easier due to its widespread use in internet APIs. Integration across various domains and technologies, application performance, and data exchange are improved by JSON.

Summary

Finally, we have completed this extensive journey in which we indeed did not leave any stone unturned in our course to learn how we could convert SQL data into JSON format. We learned about many theoretical concepts, and we even got hands-on experience with the help of the code examples that we performed.

Towards the end, we covered topics about converting the JSON format into various file types, error handling, various use cases, and real-world applications for the knowledge that we gained earlier.

References

Stackoverflow Query

Investigate Python for SQL to JSON conversion to deepen your understanding beyond that provided by the preceding article. By exploring intricate data structures and seeing how to convert SQL to JSON in practice, the diverse ecosystem of libraries available in Python can be learned.

Python is a great option for this work, whether you’re a novice or an experienced developer, due to its simplicity and adaptability. You may succeed in current software development, take on new data difficulties, and boost your creativity with the effective use of JSON-formatted data. The thrill and limitless opportunities that Python provides for data transformation need to be accepted

Make Python your entryway to a world of prosperity and innovation!