0

I am using sqlite3 which requires us to put trailing comma after the last item of tuple (of values). The example below should return an expected output of (2, 3,). Is there a builtin function that can handle this?

args = 2, 3

print(args)
# (2, 3)

print((args,))
# ((2, 3),)

sqlite3 without trailing comma after 'John'

import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute("SELECT * FROM stocks WHERE first_name = ?", ('John'))
print(c.fetchall())
conn.close()

# sqlite3.ProgrammingError: Incorrect number of bindings supplied. The
# current statement uses 1, and there are 4 supplied.

sqlite3 with trailing comma after 'John'

import sqlite3

conn = sqlite3.connect('test.db')
c = conn.cursor()
c.execute("SELECT * FROM stocks WHERE first_name = ?", ('John',))
print(c.fetchall())
conn.close()

# [(1, 'John')]
bad_coder
  • 11,289
  • 20
  • 44
  • 72
  • 3
    Where does sqlite3 require that? – melpomene Aug 31 '19 at 02:13
  • I've got `sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied`. The way I solve the problem is to add a trailing comma on the last part of the tuple. –  Aug 31 '19 at 02:17
  • I think the op uses sqllite3 package in python. – syrkull Aug 31 '19 at 02:18
  • 1
    If you have a problem with your code, you need to show your code. – melpomene Aug 31 '19 at 02:19
  • I don't think the trailing comma is required, but it might be good coding practice. – Tim Biegeleisen Aug 31 '19 at 02:19
  • 3
    Trailing commas are only required for tuples of 1 element – Iain Shelvington Aug 31 '19 at 02:19
  • @TimBiegeleisen I don't know why sqlite3 required to include trailing comma. –  Aug 31 '19 at 02:20
  • Can you share the line of code that is causing the error? – Iain Shelvington Aug 31 '19 at 02:20
  • 1
    @joumaico, sqlite **doesn't** require the trailing comma. `(2,3)` and `(2,3,)` are completely identical; no code, sqlite included, can tell them apart. – Charles Duffy Aug 31 '19 at 02:22
  • @joumaico, ...by contrast, `t1=(2,3); t2=(t1,)` is different from `t1=(2,3); t2=(t1)`, because the latter assigns `t1` directly to `t2`, instead of enclosing it in a tuple. – Charles Duffy Aug 31 '19 at 02:23
  • @joumaico, ...it's basically certain that you've got a situation like that -- where you're generating a nested tuple in one case, and a literal tuple in the other case; but the question isn't giving us enough details to address the root cause with complete certainty. – Charles Duffy Aug 31 '19 at 02:24
  • @IainShelvington I've already updated the post. –  Aug 31 '19 at 02:24
  • In `c.execute("SELECT * FROM stocks WHERE first_name = ?", ('John'))`, `('John')` **is not a tuple at all**; it only becomes a tuple when you add the comma. As soon as something is a tuple, though, whether or not there's a trailing comma is moot. – Charles Duffy Aug 31 '19 at 02:25
  • No there not a built-in as behavior is correct. By `args = 2, 3` you create a tuple, which you can prove by typing `type(args)`. By putting `args` within brackets and adding a comma `(args,)` you create a tuple of tuples. Without the comma args would just stay a tuple, like you can put `1+1` within brackects `(1+1)` and get the same result of 2. – Bruno Vermeulen Aug 31 '19 at 02:25
  • BTW, the "four arguments" the error message talks about are the four letters in the string `John`; as when a string is treated as a sequence, one gets the individual characters. – Charles Duffy Aug 31 '19 at 02:31
  • The point is that `sqlite3` requires a `tuple` parameter when using `?` placeholders, even if only one. The trailing comma is just part of python's syntax. – hpaulj Aug 31 '19 at 05:48

2 Answers2

2

Your statements differ in the following detail:

('John')  ## this is not a tuple, it just evaluates to the string 'John'
('John',) ## this *is* a tuple, containing a string 'John' as its only element

However, that difference exists only in the case where a tuple has only one item.

('John', 'Sue') == ('John', 'Sue',)

...is a true statement, because as soon as you have more than one item, the value unambiguously parses as a tuple; no trailing comma is needed.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thank you, accidentally I `args = 1,` to make the args a tuple instead of string. –  Aug 31 '19 at 02:35
  • I have finally seen the exact term for this: `In Python, a tuple containing a single value must include a comma. For example, ('abc') is evaluated as a scalar while ('abc',) is evaluated as a tuple.` Thank you Charles. https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html –  Aug 31 '19 at 10:00
0

This is not possible. Because you are using a tuple and a comma is required if you have one element. Use a list instead by replacing your parenthesis () with brackets [].

syrkull
  • 2,295
  • 4
  • 35
  • 68