Как параметризовать и передать значения в SQL "IN (?, ..., ?)", не зная заранее количества параметров?

Как можно использовать местозаполнитель (?) в условии IN?

В функцию передаю список. Есть вариант только создать ещё списки и выполнить executemany, но хотелось бы просто выполнить 1 раз запрос.

def update_completed_tasks(conn, user_id: int, tasks_id: list):
    cursor = conn.cursor()
    sql = """
        UPDATE Tasks
        SET Completed = 1
        WHERE User = ? AND task_id IN (?)
    """
    cursor.execute(sql, [user_id, [*tasks_id]])  # не сработает
    conn.commit()

Решение через доп. список:

def update_completed_tasks(conn, user_id: int, tasks_id: list):
    cursor = conn.cursor()
    temp = []
    for it in tasks_id:
        temp.append([user_id, it])
    sql = """
        UPDATE Tasks
        SET Completed = 1
        WHERE User = ? AND task_id = ?
    """
    cursor.executemany(sql, temp)
    conn.commit()

Ответы (1 шт):

Автор решения: MaxU

попробуйте так:

sql_pat = """
        UPDATE Tasks
        SET Completed = 1
        WHERE User = ? AND task_id IN ({})
"""
sql = sql_pat.format(",".join("?" * len(tasks_id)))
cursor.execute(sql, [user_id]+ tasks_id)

пример:

In [6]: user_id = 111; tasks_id = [21, 22, 23]

In [7]: sql = sql_pat.format(",".join("?" * len(tasks_id)))

In [8]: print(sql)

        UPDATE Tasks
        SET Completed = 1
        WHERE User = ? AND task_id IN (?,?,?)


In [9]: params = [user_id]+ tasks_id

In [10]: print(params)
[111, 21, 22, 23]
→ Ссылка