Python sqlite3.ProgrammingError: parameters are of unsupported type

Updated: February 6, 2024 By: Guest Contributor Post a comment

Introduction

When working with SQLite databases in Python using the sqlite3 library, you might encounter the sqlite3.ProgrammingError: parameters are of unsupported type error. This error typically arises when the parameter values passed to a SQL query are not in a format that SQLite can understand. In this tutorial, we will explore the causes of this error and provide multiple solutions to resolve it.

Understanding the Error

This error occurs when executing a SQL query through the sqlite3 module in Python, and the parameters supplied to the query do not match the expected type. SQLite expects parameters in specific formats, and deviation from these can lead to errors.

Solution 1: Use Correct Data Types

Ensure all parameter values passed to the SQL query are in the correct data types expected by SQLite. SQLite supports data types like TEXT, INTEGER, REAL, BLOB, etc., and passing parameters that do not conform to these expected types can result in errors.

Steps

  1. Identify the data type expected by each column in your SQL query.
  2. Convert the parameters to match these data types before passing them to the query.

Code Example

import sqlite3

def create_user(conn, user_data):
    sql = 'INSERT INTO users(name, age) VALUES(?, ?)'
    cur = conn.cursor()
    cur.execute(sql, user_data)
    conn.commit()

conn = sqlite3.connect('users.db')
user_data = ('John Doe', 30)  # Correct data types: a string and an integer
create_user(conn, user_data)

This solution is straightforward but requires a good understanding of the expected data types within your database schema. Always ensure parameters match the expected types closely.

Solution 2: Using Parameterized Queries

Another common cause of this error is not using parameterized queries properly. Parameterized queries not only enhance security by preventing SQL injection but also help in ensuring that parameters are correctly passed to the SQL statement.

Steps to Implement

  1. Always use placeholders for parameters in SQL queries.
  2. Pass parameters as a tuple or a dictionary to the execute() method.

Example

import sqlite3

def update_user_age(conn, age, user_id):
    sql = 'UPDATE users SET age = ? WHERE id = ?'
    cur = conn.cursor()
    cur.execute(sql, (age, user_id))
    conn.commit()

conn = sqlite3.connect('users.db')
update_user_age(conn, 35, 1)  # Passing parameters as a tuple

Using parameterized queries is a best practice in SQL operations. It mitigates the risk of SQL injection and clarifies the code by separating SQL commands from the data being input.

Solution 3: Converting Unsupported Objects

If you are passing custom objects or unsupported types (such as datetime objects directly to SQLite), you’ll likely encounter this error. Convert these objects to a supported string or numeric format before passing them to your SQL query.

Steps to Implement

  1. Identify any parameter that is of an unsupported type by SQLite.
  2. Convert these parameters to a string or a numeric type.
  3. Pass the converted parameters to the SQL query.

Example

import sqlite3
from datetime import datetime

def add_event(conn, event_date):
    sql = 'INSERT INTO events(date) VALUES(?)'
    cur = conn.cursor()
    # Convert datetime object to string in SQLite-friendly format
    cur.execute(sql, (event_date.strftime('%Y-%m-%d'),))
    conn.commit()

conn = sqlite3.connect('events.db')
add_event(conn, datetime.now())

Converting unsupported objects to supported types can avoid this error and also makes the database more flexible, allowing the use of rich Python objects in your application logic while still working smoothly with the database.