Is there a way to dynamically use the SQLite IN command in Python without providing the exact number of placeholders?
For instance, let's say I'm trying to get:
SELECT
*
FROM mytable
WHERE somecol IN (1, 3, 4, 7, 9)
In Python, a placeholder is a tuple of at least length 1, but I'm not sure how (or even if it is possible) to use them with the IN command. I have tried pure tuples, stringed tuples and pure strings, both free and enclosed, all to no avail:
In [1]: import sqlite3
...: conn = sqlite3.connect(':memory:')
...: cur = conn.cursor()
...: l = [(i, chr(i+64)) for i in range(1, 11)]
...: cur.execute('CREATE TABLE mytable (somecol INTEGER, char TEXT)')
...: cur.executemany('INSERT INTO mytable VALUES(?, ?)', l)
...: conn.commit()
In [2]: tup = ((1, 3, 4, 7, 9),)
...: cur.execute('SELECT * FROM mytable WHERE somecol IN ?', tup)
OperationalError Traceback (most recent call last)
<ipython-input-2-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM mytable WHERE somecol IN ?', tup).fetchall()
OperationalError: near "?": syntax error
In [3]: cur.execute('SELECT * FROM mytable WHERE somecol IN (?)', tup).fetchall()
---------------------------------------------------------------------------
InterfaceError Traceback (most recent call last)
<ipython-input-2-a6c2d28cce18> in <module>
----> 1 cur.execute('SELECT * FROM mytable WHERE somecol IN (?)', tup).fetchall()
InterfaceError: Error binding parameter 0 - probably unsupported type.
In [4]: tups = tuple(str(i) for i in tup)
...: cur.execute('SELECT * FROM mytable WHERE somecol IN ?', tups)
OperationalError Traceback (most recent call last)
<ipython-input-3-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM mytable WHERE somecol IN ?', tups).fetchall()
OperationalError: near "?": syntax error
In [5]: # Empty list due to trying to fetch a somecol string value of "(1, 3, 4, 7, 9)"
...: cur.execute('SELECT * FROM mytable WHERE somecol IN (?)', tups).fetchall()
Out[5]: []
In [6]: stup = (', '.join(str(i) for i in tup[0]),)
...: cur.execute('SELECT * FROM mytable WHERE somecol IN ?', stup)
OperationalError Traceback (most recent call last)
<ipython-input-5-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM mytable WHERE somecol IN ?', stup).fetchall()
OperationalError: near "?": syntax error
In [7]: # Empty list due to trying to fetch a somecol string value of "1, 3, 4, 7, 9"
...: cur.execute('SELECT * FROM mytable WHERE somecol IN (?)', stup).fetchall()
Out[7]: []
I know that if I provide cur.execute('SELECT * FROM mytable WHERE somecol IN (?, ?, ?, ?, ?)', tup[0]).fetchall() I will get the desired result, but that's because I know the length of tup[0] beforehand and adjusted the cursor accordingly. However, this will break down on applications where I can't anticipate that.
I'm almost sure this is actually not feasbile in Python, but I'm wondering why it is and should be so?
The sequence placeholder supported by other databases isn't supported by sqlite.
To get around this you just generate as many single placeholders in a sequence as needed. Via like: '(' + ','.join('?'*len(v)) + ')'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With