使用pyodbc和mysql8的参数化查询对于int数据类型的列返回0 Python:2.7.12 pyodbc:4.0.24 操作系统:Ubuntu 16.4 数据库:MySQL 8 驱动程序:MySQL 8
预期行为:resultset应在数据类型为int的列中包含数字 实际行为:如果使用参数化查询,则int数据类型的所有列都具有0 以下是问题- 1. 结果集:使用pyodbc和mysql8的参数化查询对于int数据类型的列返回0 Python:2.7.12 pyodbc:4.0.24 操作系统:Ubuntu 16.4 数据库:MySQL 8 驱动程序:MySQL 8,python,mysql,pyodbc,Python,Mysql,Pyodbc,预期行为:resultset应在数据类型为int的列中包含数字 实际行为:如果使用参数化查询,则int数据类型的所有列都具有0 以下是问题- 1. 结果集: [(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(2
[(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.
或
或
结果集:
[(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;
您在MySQL连接器/ODBC中遇到了一些问题
编辑:错误
以下Python 3测试代码验证MySQL Connector/ODBC返回的值是否为零不正确,同时返回的值是否正确:
从mysqlclient导入MySQLdb
导入pyodbc
主机='localhost'
用户='root'
passwd='whatever'
db='mydb'
端口=3307
字符集='utf8mb4'
使用_odbc=False或True
printf'{如果使用odbc,否则不使用}使用odbc…'
如果使用odbc,请执行以下操作:
连接字符串=
f'DRIVER=MySQL ODBC 8.0 ANSI驱动程序;'
f'SERVER={host};UID={user};PWD={passwd};数据库={db};端口={PORT};'
f'charset={charset};'
cnxn=pyodbc.connectconnection\u字符串
printf'{cnxn.getinfopyodbc.SQL_DRIVER_NAME},版本{cnxn.getinfopyodbc.SQL_DRIVER_VER}'
其他:
cnxn=MySQLdb.connect
host=host,user=user,passwd=passwd,db=db,port=port,charset=charset
int_值=123
crsr=cnxn.cursor
crsr.executeCREATE临时表foo id varchar10主键,intcol int,othercol longblob
crsr.executefINSERT到foo id,intcol值'Alfa',{int_value}
sql=fSELECT intcol,othercol FROM foo,其中id={'?'如果使用_odbcelse'%s'}
crsr.executesql,“阿尔法”,
结果=crsr.fetchone[0]
printf'{result==int\u value else FAIL}时通过-应为:{reprint\u value};实际:{reprresult}'
use_odbc=True的控制台输出:
使用ODBC。。。
myodbc8a.dll,版本08.00.0018
预期失败:123;实际:0
使用odbc=False的控制台输出:
不使用ODBC。。。
预期通过:123;实际:123
FWIW我刚刚发布了一个问题,我在ODBC连接器的3.1.14版中看到了这一点,但在3.1.10版中没有看到。@snakecharmerb如果您需要任何可能相关的进一步信息,请告诉我:但对我来说,这似乎是相当基本的用例。人们是如何做到这一点的?我怀疑大多数使用Python的MySQL的人都在使用而不是pyodbc。感谢您的回复。我试过了,得到了以下错误:>>>cursor.executeSELECT*来自患者,患者id=?,“7”,回溯最近的调用:文件,第1行,在文件/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py,第210行,在execute query=query%args TypeError中:并非所有在字符串格式化过程中转换的参数@Gord ThompsonIt看起来像MySQLdb使用%s而不是?在参数化查询中。你能确认@Gord吗Thompson@Simrankaurre:参数占位符-是的,你是正确的。因此,如果不更改参数占位符,就无法使用MySQLdb?我本想避免在我的所有查询中进行此更改@Gord ThompsonI在MySQL中创建了您的患者表,并试图重现您的问题,但我无法通过pyodbc使用MySQL Connector/ODBC 8.00.18或使用mysqlclient。在任何情况下,ODBC 8.x的另一种可能的解决方法是首先只选择int列,然后再进行第二次选择以检索相同行的其余列。或者,您可以退回到动态SQL,对于SELECT*。。。如果patient_id=7,则不会造成SQL注入问题的重大风险
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'))]
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;