views:

320

answers:

1

Hi,

I'm using pyodbc to talk to a legacy Access 2000 .mdb file.

I've got a cursor, and am trying to execute this:

c.execute("INSERT INTO [Accounts] ([Name], [TypeID], [StatusID], [AccountCat], [id]) VALUES (?, ?, ?, ?, ?)", [u'test', 20, 10, 4, 2])

However, doing so results in

pyodbc.Error: ('HYC00', '[HYC00] [Microsoft][ODBC Microsoft Access Driver]Optional feature not implemented  (106) (SQLBindParameter)')

I understand I can simply change the question marks to the literal values, but in my experience proper escaping of strings across databases is... not pretty.

PHP and mysql team up to bring mysql_real_escape_string and friends, but I can't seem to find pyodbc's function for escaping values.

If you could let me know what the recommended way of inserting this data (from python) is, that'd be very helpful. Alternatively, if you have a python function to escape the odbc strings, that would also be great.

Thanks for the help.

A: 

Well, apparently this is just Access yelling at me again.

Previously, I had been inserting python integers. Now, I have tried to insert python longs.

When inserting a long as a parameter, I get

pyodbc.Error: ('HYC00', '[HYC00] [Microsoft][ODBC Microsoft Access Driver]Optional feature not implemented  (106) (SQLBindParameter)')

Adding this code to my function just before calling the execute fixes it:

    for k, v in new.items():
        new[k] = int(v) if isinstance(v, long) else v

IOW, replacing longs with ints works fine. Go Access, what a descriptive error.

Strictly speaking, I don't think this is a bug in pyodbc, but rather a gotcha when dealing with this particular driver. Thanks for the help anyway.

MDBGuy
What is the definition of the Python long data type? If it exceeds the capacity of the Jet long integer, then that's why you can't use it. If that's the cause of the problem, it looks like pilot error to me, i.e., you tried to do something without fully understanding the data types of the target db.
David-W-Fenton
In Python, longs have an arbitrary capacity. Python will transparently promote ints to longs when necessary, but it doesn't demote automatically (so int(24) is an integer while long(24) is a long, but both int(2400000000) and long(2400000000) are longs). So it's perfectly reasonable for a Python programmer to be unaware of whether their program is using longs, ints, or a mix of the two under the covers. And it's not unreasonable to expect pyodbc to accept both, if they're in range.
Chris B.