Параметризованный запрос с pyodbc и mysql8 возвращает 0 для столбцов с типами данных int - PullRequest
2 голосов
/ 02 ноября 2019
  • Python: 2.7.12
  • pyodbc: 4.0.24
  • ОС: Ubuntu 16.4
  • БД: MySQL 8
  • драйвер:MySQL 8

Ожидаемое поведение: результирующий набор должен иметь числа в столбцах с типом данных int

Фактическое поведение: Все столбцы с типом данных int имеют 0 (если параметризованный запросиспользуется)

Вот вопросы -

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

Набор результатов:

[(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])`

или

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

или

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

Набор результатов:

[(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'))]

Остальная часть набора результатов в порядкеза исключением столбцов с типом данных int, которые имеют все 0, если используется параметризованный запрос.

Кажется, это должно было работать без проблем. Могу ли я получить помощь здесь.

Редактировать: Вот схема таблицы:

 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 ]

3 голосов
/ 03 ноября 2019

Вы столкнулись с этой ошибкой в MySQL Connector / ODBC.

Следующий (Python 3) тестовый код проверяет, что MySQL Connector / ODBC возвращает ноль (неверный), в то время как mysqlclient возвращает правильное значение:

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)}')

Консольный вывод с use_odbc = True:

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

Консольный вывод с use_odbc = False:

not using ODBC ...
pass -- expected: 123 ; actual: 123
1 голос
/ 04 ноября 2019

FWIW Я только что опубликовал вопрос, где я видел это в версии 3.1.14 разъема ODBC, но НЕ в версии 3.1.10.

...