KSHMR
KSHMR

Reputation: 809

"No such column" when searching in sqlite3 in python

My table, "info", has 4 columns: bp, key, exp and job. I'm trying to create a function that searches for a term within a specified column:

Edit: Different problem, see 2nd code and 2nd error below

def search2(query, field):

    search_string = query    

    if field == "bp":
        cursor.execute("SELECT * FROM info WHERE bp="+search_string)
    elif field == "key":
        cursor.execute("SELECT * FROM info WHERE key="+search_string)
    elif field == "exp":
        cursor.execute("SELECT * FROM info WHERE exp="+search_string)
    elif field == "job":
        cursor.execute("SELECT * FROM info WHERE job="+search_string)

However, this raises an error, with "test" as search string and "bp" as column:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\user\Programs\time_database.py", line 32, in search2
    cursor.execute("SELECT * FROM info WHERE bp="+search_string)
sqlite3.OperationalError: no such column: test

And by the way, "test" wasn't intended to be a column. I want it to be a search string that matches the specified column...

EDIT

Thanks Martijn Pieters for that, but now another error has surfaced. My code now is:

def search2(query, field):

    search_string = query    

    if field == "bp":
        cursor.execute("SELECT * FROM info WHERE job=?", search_string)
    elif field == "key":
        cursor.execute("SELECT * FROM info WHERE key="+search_string)
    elif field == "exp":
        cursor.execute("SELECT * FROM info WHERE exp="+search_string)
    elif field == "job":
        cursor.execute("SELECT * FROM info WHERE job="+search_string)

And the error I get is:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\gummi\Programs\time_database.py", line 32, in search2
    cursor.execute("SELECT * FROM info WHERE job=?", search_string)
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement         uses 1, and there are 4 supplied.

Upvotes: 2

Views: 3005

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121644

You are not quoting the search string, and the database is interpreting it as a column name instead.

Use query parameters, these quote your search string automatically:

cursor.execute("SELECT * FROM info WHERE job=?", search_string)

Next, if the field (column) value is not coming from an untrusted source (such as a web page) you can interpolate it directly into your query:

cursor.execute("SELECT * FROM info WHERE %s=?" % field, (search_string,))

Now you no longer need all the branching.

If the field value does come from an untrusted source, the simplest thing is to just test if it is an allowed value:

def search2(query, field):
    if field not in set(['bp', 'key', 'exp', 'job']):
        raise ValueError('No such column ' + field)    
    cursor.execute("SELECT * FROM info WHERE %s=?" % field, (query,))

Upvotes: 4

Related Questions