'"Optional feature not implemented (106) (SQLBindParameter)" error with pyodbc

I'm being driven nuts trying to figure this one out. I'm using Python for the first time, and trying to write data collected from twitter out to an Access 2010 database.

The command I'm using is:

cursor.execute('''insert into core_data(screen_name,retweet_count) values (?,?,)''', (sname,int(rcount)))

The error message being returned is:

Traceback (most recent call last):  File "C:/Documents and Settings/Administrator/PycharmProjects/clientgauge/tw_scraper.py", line 44, in <module>
cursor.execute('''insert into core_data(screen_name,retweet_count) values (?,?,)''', (sname,int(rcount))) 
pyodbc.Error: ('HYC00', '[HYC00] [Microsoft][ODBC Microsoft Access Driver]Optional feature not implemented  (106) (SQLBindParameter)')

I've tried various permutations of passing the data into the db. If I remove the int(rcount) entry, it will post the first value, sname, without any issues. As soon as I try to pass in more than one parameter though, this is when the problems start.

I have a feeling I'm missing something really basic, but I can't find any examples of this which actually have a similar look to what I'm trying to do, and what I'm trying is NOT difficult...user error probably :)

Any help would be much appreciated.

Cheers, Kev

Complete code is:

from twython import Twython
import pyodbc
ACCESS_DATABASE_FILE = 'C:\\data\\ClientGauge.accdb'
ODBC_CONN_STR = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;' %ACCESS_DATABASE_FILE
cnxn = pyodbc.connect(ODBC_CONN_STR, autocommit=True)
cursor = cnxn.cursor()
APP_KEY = '<removed>'
APP_SECRET = '<removed>'
# Authenticate on twitter using keys above
t = Twython(APP_KEY, APP_SECRET, oauth_version=2)
# Obtain new access token for this session
ACCESS_TOKEN = t.obtain_access_token()
# Authenticate using new access token
t = Twython(APP_KEY, access_token=ACCESS_TOKEN)
# Carry out search
search = t.search(q='<removed>', #**supply whatever query you want here**
         count=1, result_type='recent')
tweets = search['statuses']
for tweet in tweets:
sname=tweet['user']['screen_name']
rcount=int(tweet['retweet_count'])
fcount=tweet['favorite_count']
coord=tweet['coordinates']
tzone=tweet['user']['time_zone']
cdate=tweet['created_at']
htags=tweet['entities']['hashtags']
sql = "insert into core_data(screen_name,retweet_count,favourited_count) values (?,?,?)", (str(sname),rcount,fcount)
print(sql)
cursor.execute('''insert into core_data(screen_name,retweet_count) values (?,?)''', (sname,rcount))
cursor.commit()
cnxn.close()

I'm using MS Access 2010, pyodbc-3.0.7.win32-py3.3.exe, Python 3.3 & PyCharm.

Don't judge my coding prowess :) Python is new to me. You'll be able to see that I've tried setting the INSERT statement up as a string initially (sql), and I was calling the cursor using:

cursor.execute(sql)

Unfortunately, this didn't work for me either! If I replace the second parameter with a number such as 1...it still doesn't work. Frustrating.



Solution 1:[1]

You've got an extra comma in your parameters list that is messing you up. The following code works for me under Python 2.7:

import pyodbc
sname = 'Gord'
rcount = 3
cnxn = pyodbc.connect(
        'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' +
        'DBQ=C:\\Users\\Public\\Database1.accdb;')
cursor = cnxn.cursor()
sql = "insert into core_data(screen_name,retweet_count) values (?,?)"
params = (sname, int(rcount))
cursor.execute(sql, params)
cursor.commit()
cnxn.close()

Edit:

It turns out that there is a reported issue with integer parameters when pyodbc interacts with Access ODBC while running under under Python 3.x. One possible workaround would be to try downloading and installing pypyodbc and then trying this code (which works for me under Python 3.5.2):

import pypyodbc
sname = 'Gord'
rcount = 3
cnxn = pypyodbc.connect(
        'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};' +
        'DBQ=C:\\Users\\Public\\Database1.accdb;')
cursor = cnxn.cursor()
sql = "insert into core_data(screen_name,retweet_count) values (?,?)"
params = (sname, rcount)
cursor.execute(sql, params)
cursor.commit()
cnxn.close()

Solution 2:[2]

I had the same error with this driver and pyodbc, it turned out that converting integers to floats solved the issue:

row = [1, 2, "foo"]
row = [float(x) if type(x) is int else x for x in row] #Convert all int items to floats
cursor.execute("insert into table1 (a,b,c) values (?,?,?)",row).commit()

Solution 3:[3]

This error is usually associated with ODBC SQL Driver version. See issue here.

Solution 4:[4]

I had the same issue but for me it had to do with the driver configuration.

I had enabled fast selects in the ODBC driver config, which I confirmed was the cause of me getting this error.

Posting this just in case someone else had fiddled with their driver settings and the proposed solutions aren't what they were looking for as in my case.

Solution 5:[5]

pyodbc.Error: ('HYC00', '[HYC00] [Oracle][ODBC Oracle Driver]Optional feature not implemented

I had this error show up due to the below issue:
Had 2 columns already in my dataframe say 'X', 'Y'. Only 'X' was in my list of columns to be inserted in the database.
Before inserting, I was trying to change the column name 'Y' to 'X' (using df.rename(columns={'Y': 'X'})) thus asking for duplicate columns (2 'X' columns). It wasn't creating 2 'X' columns but rather throwing the exception.

Fix--> I had to consistently populate only column 'X' in my code and no 'Y' anywhere

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 vivekagr
Solution 3 Marko Tankosic
Solution 4 Sibs
Solution 5 Suraj Rao