使用SQLAlchemy连接SQL Server时HY104精度错误求助
排查SQLAlchemy连接SQL Server时的HY104错误思路
问题背景
数据库连接代码
from sqlalchemy import text , create_engine Server = '' Database = '' Driver = 'SQL Server' Database_Con = f'mssql://@{Server}/{Database}?driver={Driver}' # 创建数据库连接引擎 engine=create_engine(Database_Con) con = engine.connect()
插入数据时的报错信息
(pyodbc.Error) ('HY104', '[HY104] [Microsoft][ODBC SQL Server Driver]Invalid precision value (0) (SQLBindParameter)') [SQL: SELECT [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] FROM [INFORMATION_SCHEMA].[TABLES] WHERE ([INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = CAST(? AS NVARCHAR(max)) OR [INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = CAST(? AS NVARCHAR(max))) AND [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] = CAST(? AS NVARCHAR(max)) AND [INFORMATION_SCHEMA].[TABLES].[TABLE_SCHEMA] = CAST(? AS NVARCHAR(max))] [parameters: ('BASE TABLE', 'VIEW', '', 'dbo')]
已知限制:无法升级/安装新驱动;修改varchar(max)为varchar(4000)未解决问题;目标表包含datetime列。
排查步骤
- 检查空参数的处理逻辑:报错SQL中第三个参数是空字符串
'',对应TABLE_NAME字段。旧版ODBC驱动对空字符串绑定到NVARCHAR(max)可能存在精度识别问题,尝试给该参数指定非空默认值(比如临时用一个不存在的表名占位,或确认业务逻辑中是否允许TABLE_NAME为空),避免传递空字符串参数。 - 强制指定参数的数据类型精度:在SQLAlchemy绑定参数时,显式指定参数的类型和精度,比如将空字符串参数指定为
NVARCHAR(128)而非默认的NVARCHAR(max)。示例代码:from sqlalchemy import String # 手动编写查询语句并指定参数类型 stmt = text(""" SELECT [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] FROM [INFORMATION_SCHEMA].[TABLES] WHERE ([INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = :table_type1 OR [INFORMATION_SCHEMA].[TABLES].[TABLE_TYPE] = :table_type2) AND [INFORMATION_SCHEMA].[TABLES].[TABLE_NAME] = :table_name AND [INFORMATION_SCHEMA].[TABLES].[TABLE_SCHEMA] = :schema """) con.execute(stmt, table_type1=('BASE TABLE', String(128)), table_type2=('VIEW', String(128)), table_name=('', String(128)), schema=('dbo', String(128))) - 验证datetime列的参数格式:目标表包含
datetime列,检查插入数据中datetime类型的值是否符合旧ODBC驱动的格式要求。避免传递Python的datetime.datetime对象时出现精度溢出,或尝试将datetime转换为%Y-%m-%d %H:%M:%S格式的字符串后再插入。 - 调整连接字符串的驱动兼容参数:旧版
SQL Server驱动对max类型支持有限,尝试在连接字符串中添加DataTypeCompatibility=80参数,强制驱动使用兼容模式处理数据类型。示例连接字符串:Database_Con = f'mssql://@{Server}/{Database}?driver={Driver}&DataTypeCompatibility=80' - 规避自动生成的CAST逻辑:SQLAlchemy自动生成的
CAST(? AS NVARCHAR(max))语句可能触发驱动bug,尝试手动编写表结构查询语句,直接使用固定长度的NVARCHAR类型,避免自动转换逻辑。
内容的提问来源于stack exchange,提问作者SC_Python
相关产品推荐
相关产品推荐

