Sling Academy
Home/Python/Python sqlite3: Type Conversion (Implicit/Explicit)

Python sqlite3: Type Conversion (Implicit/Explicit)

Last updated: February 06, 2024

Introduction

Working with databases in Python is a task that you’ll likely encounter at some point in your development journey. SQLite3, a database engine included with Python, makes database interaction seamless and efficient. A crucial aspect of interacting with SQLite databases is understanding how type conversion works, both implicitly and explicitly. In this article, we dive deep into this topic, covering everything from the basics to more advanced examples, accompanied by code snippets.

Understanding SQLite Type Affinity

Before diving into type conversion mechanisms in SQLite3, it’s essential to understand the concept of type affinity. SQLite uses dynamic typing. It means that the datatype of a value is associated with the value itself, not with its container. However, columns in SQLite are recommended to have a preferred data type, known as type affinity. This concept primarily influences how SQLite handles the type conversion implicitly.

Implicit Type Conversion

Implicit type conversion, or type coercion, in SQLite3, occurs automatically based on context. For example, when inserting data, SQLite tries to convert the values into the storage class of the respective column, following its type affinity rules.

import sqlite3

conn = sqlite3.connect('example.db')
cur = conn.cursor()

cur.execute('CREATE TABLE test (id INTEGER, info TEXT)')
# Inserting a string that looks like an integer
cur.execute('INSERT INTO test (id, info) VALUES (?, ?)', (1, '100'))

# Retrieving the value
cur.execute('SELECT * FROM test')
print(cur.fetchone())

The output of this simple example will be:
(1, '100')
Even though ‘100’ was inserted as a string, it’s stored based on the column’s type affinity which is TEXT in this case.

Explicit Type Conversion

Explicit type conversion, on the other hand, requires direct intervention in the form of casting or using conversion functions. This is particularly useful when you need exact control over how the data is stored or retrieved.

import sqlite3

conn = sqlite3.connect('example.db')
cur = conn.cursor()

cur.execute('SELECT CAST(info AS INTEGER) FROM test')
print(cur.fetchone())

In this case, the CAST function is explicitly converting the info field from TEXT to INTEGER. The output will be:
(100,)

Dealing with Timestamps

Manipulating timestamps is a typical scenario where explicit type conversion becomes invaluable. SQLite3 stores timestamps in TEXT, REAL, or INTEGER formats, however, dealing with them in Python generally involves datetime objects.

import sqlite3
from datetime import datetime, date

conn = sqlite3.connect('example.db')
cur = conn.cursor()

cur.execute('CREATE TABLE dates (event TEXT, date_happened TIMESTAMP)')

today = datetime.now()
cur.execute('INSERT INTO dates (event, date_happened) VALUES (?, ?)', ('My Event', today))

# Converting TIMESTAMP to datetime object when selecting
cur.execute('SELECT date_happened FROM dates')
raw_date = cur.fetchone()[0]
converted_date = datetime.strptime(raw_date, '%Y-%m-%d %H:%M:%S')

print(converted_date)

The output will be a datetime object representing the current time when the insertion was made. This demonstrates how you can use explicit type conversion to handle complex data types like timestamp effectively.

Advanced Example: Custom Type Adapters and Converters

Moving towards more sophisticated use cases, SQLite3 allows for the customization of type conversion through the use of adapters and converters. This means you can define how Python objects are stored in the database and how database values are converted back into Python objects.

import sqlite3

sqlite3.register_adapter(datetime, lambda x: x.strftime('%Y-%m-%d %H:%M:%S'))
sqlite3.register_converter('TIMESTAMP', lambda x: datetime.strptime(x.decode('utf-8'), '%Y-%m-%d %H:%M:%S'))

conn = sqlite3.connect('example.db', detect_types=sqlite3.PARSE_DECLTYPES)
cur = conn.cursor()

cur.execute('CREATE TABLE custom_date (event TEXT, date_happened TIMESTAMP)')

today = datetime.now()
cur.execute('INSERT INTO custom_date (event, date_happened) VALUES (?, ?)', ('Another Event', today))

# Now when retrieving, the date_happened column is automatically converted
# back to a datetime object.
cur.execute('SELECT date_happened FROM custom_date')
print(cur.fetchone()[0])

This code sample demonstrates how to register custom adapters and converters to handle complex types more effectively, providing a powerful level of abstraction and ease of use.

Conclusion

In conclusion, understanding type conversion in SQLite3 is crucial for developers who need to work with databases in Python. By mastering implicit and explicit type conversion, you can ensure data integrity and ease the interaction with databases. Whether you’re handling simple value transformations or complex custom type adaptations, Python and SQLite3 together provide a robust platform to meet your database interaction needs.

Next Article: Python sqlite3 warning: ‘You can only execute one statement at a time’

Previous Article: Python sqlite3.ProgrammingError: parameters are of unsupported type

Series: Data Persistence in Python – Tutorials & Examples

Python

You May Also Like

  • Introduction to yfinance: Fetching Historical Stock Data in Python
  • Monitoring Volatility and Daily Averages Using cryptocompare
  • Advanced DOM Interactions: XPath and CSS Selectors in Playwright (Python)
  • Automating Strategy Updates and Version Control in freqtrade
  • Setting Up a freqtrade Dashboard for Real-Time Monitoring
  • Deploying freqtrade on a Cloud Server or Docker Environment
  • Optimizing Strategy Parameters with freqtrade’s Hyperopt
  • Risk Management: Setting Stop Loss, Trailing Stops, and ROI in freqtrade
  • Integrating freqtrade with TA-Lib and pandas-ta Indicators
  • Handling Multiple Pairs and Portfolios with freqtrade
  • Using freqtrade’s Backtesting and Hyperopt Modules
  • Developing Custom Trading Strategies for freqtrade
  • Debugging Common freqtrade Errors: Exchange Connectivity and More
  • Configuring freqtrade Bot Settings and Strategy Parameters
  • Installing freqtrade for Automated Crypto Trading in Python
  • Scaling cryptofeed for High-Frequency Trading Environments
  • Building a Real-Time Market Dashboard Using cryptofeed in Python
  • Customizing cryptofeed Callbacks for Advanced Market Insights
  • Integrating cryptofeed into Automated Trading Bots