Parameterized query with pyodbc and mysql8 returns 0 for columns with int data types

大兔子大兔子 提交于 2019-12-01 07:35:16

问题


  • Python: 2.7.12
  • pyodbc: 4.0.24
  • OS: Ubuntu 16.4
  • DB: MySQL 8
  • driver: MySQL 8

Expected behaviour: resultset should have numbers in columns with datatype int

Actual Behaviour: All of the columns with int data type have 0's (If parameterised query is used)

Here's the queries -

    1.
cursor.execute("SELECT * FROM TABLE where id =7")

Result set:

[(7, 1, None, 1, u'An', u'Zed', None, u'Ms', datetime.datetime(2016, 12, 20, 0, 0), u'F', u'Not To Be Disclosed', None, None, u'SPRING', None, u'4000', datetime.datetime(2009, 5, 20, 18, 55), datetime.datetime(2019, 1, 4, 14, 25, 58, 763000), 0, None, None, None, bytearray(b'\x00\x00\x00\x00\x01(n\xba'))]
    2.
cursor.execute("SELECT * FROM patients where patient_id=?", [7])`

or

cursor.execute("SELECT * FROM patients where patient_id=?", ['7'])

or

cursor.execute("SELECT * FROM patients where patient_id IN ", [7])

Result set:

[(0, 0, None, 0, u'An', u'Zed', None, u'Ms', datetime.datetime(2016, 12, 20, 0, 0), u'F', u'Not To Be Disclosed', None, None, u'SPRING', None, u'4000', datetime.datetime(2009, 5, 20, 18, 55), datetime.datetime(2019, 1, 4, 14, 25, 58, 763000), 0, None, None, None, bytearray(b'\x00\x00\x00\x00\x01(n\xba'))]

Rest of the result set is okay except for the columns with int data type that all have 0's if paramterized query is used.

It seems like it should have worked without issues. Can I get some help here.

Edit : Here's the schema of the table:

 CREATE TABLE `patient
  `lastname` varchar(30) DEFAULT NULL,
  `known_as` varchar(30) DEFAULT NULL,
  `title` varchar(50) DEFAULT NULL,
  `dob` datetime DEFAULT NULL,
  `sex` char(1) DEFAULT NULL,
  `address1` varchar(30) DEFAULT NULL,
  `address2` varchar(30) DEFAULT NULL,
  `address3` varchar(30) DEFAULT NULL,
  `city` varchar(30) DEFAULT NULL,
  `state` varchar(16) DEFAULT NULL,
  `postcode` char(4) DEFAULT NULL,
  `datecreated` datetime NOT NULL,
  `dateupdated` datetime(6) DEFAULT NULL,
  `isrep` tinyint(1) DEFAULT NULL,
  `photo` longblob,
  `foreign_images_imported` tinyint(1) DEFAULT NULL,
  `ismerged` tinyint(1) DEFAULT NULL,
  `rowversion` varbinary(8) DEFAULT NULL,
  PRIMARY KEY (`patient_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

回答1:


You have encountered this bug in MySQL Connector/ODBC.

The following (Python 3) test code verifies that MySQL Connector/ODBC returns zero (incorrect), while mysqlclient returns the correct value:

import MySQLdb  # from mysqlclient
import pyodbc

host = 'localhost'
user = 'root'
passwd = 'whatever'
db = 'mydb'
port = 3307
charset = 'utf8mb4'

use_odbc = False  # or True
print(f'{"" if use_odbc else "not "}using ODBC ...')

if use_odbc:
    connection_string = (
        f'DRIVER=MySQL ODBC 8.0 ANSI Driver;'
        f'SERVER={host};UID={user};PWD={passwd};DATABASE={db};PORT={port};'
        f'charset={charset};'
    )
    cnxn = pyodbc.connect(connection_string)
    print(f'{cnxn.getinfo(pyodbc.SQL_DRIVER_NAME)}, version {cnxn.getinfo(pyodbc.SQL_DRIVER_VER)}')
else:
    cnxn = MySQLdb.connect(
        host=host, user=user, passwd=passwd, db=db, port=port, charset=charset
    )

int_value = 123
crsr = cnxn.cursor()
crsr.execute("CREATE TEMPORARY TABLE foo (id varchar(10) PRIMARY KEY, intcol int, othercol longblob)")
crsr.execute(f"INSERT INTO foo (id, intcol) VALUES ('Alfa', {int_value})")
sql = f"SELECT intcol, othercol FROM foo WHERE id = {'?' if use_odbc else '%s'}"
crsr.execute(sql, ('Alfa',))
result = crsr.fetchone()[0]
print(f'{"pass" if result == int_value else "FAIL"} -- expected: {repr(int_value)} ; actual: {repr(result)}')

Console output with use_odbc = True:

using ODBC ...
myodbc8a.dll, version 08.00.0018
FAIL -- expected: 123 ; actual: 0

Console output with use_odbc = False:

not using ODBC ...
pass -- expected: 123 ; actual: 123



回答2:


FWIW i just posted a question where i was seeing this in version 3.1.14 of the ODBC connector but NOT in version 3.1.10.



来源:https://stackoverflow.com/questions/58674295/parameterized-query-with-pyodbc-and-mysql8-returns-0-for-columns-with-int-data-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!