Parameterized query with pyodbc and mysql8 returns

2020-03-26 13:51发布

  • 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;

2条回答
够拽才男人
2楼-- · 2020-03-26 14:03

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.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2020-03-26 14:17

You have encountered this bug in MySQL Connector/ODBC.

EDIT: The bug has now been fixed.


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
查看更多
登录 后发表回答