SQLAlchemy执行查询无结果但DBeaver执行同查询有结果的问题排查
我来帮你分析下这个问题,看起来同一个查询在DBeaver能出结果,但SQLAlchemy里不行,大概率是连接参数或者数据库会话的配置差异导致的,咱们一步步来排查:
先确认SQLAlchemy执行的查询和DBeaver完全一致
你可以在创建engine的时候加上echo=True参数,这样SQLAlchemy会打印出实际执行的SQL语句,对比下和你在DBeaver里跑的是不是完全一样:engine = create_engine( f"mariadb+mariadbconnector://USERNAME:PASSWORD@SERVER_LOCATION_HERE", pool_pre_ping=True, pool_recycle=40, echo=True )有时候可能因为字符串转义或者隐性的参数处理问题,导致实际执行的SQL有差异,这一步先排除这个可能。
检查连接的字符集和时区配置
从你的表结构来看,Date1是text类型,存储的是带时区的字符串,当你用STR_TO_DATE(Date1, '%Y-%m-%d')转成DATE类型后,和原字符串比较时,MariaDB会做隐式类型转换,而字符集、时区的差异可能影响这个转换的结果。
你可以尝试在连接URL里指定字符集和时区,比如:engine = create_engine( f"mariadb+mariadbconnector://USERNAME:PASSWORD@SERVER_LOCATION_HERE?charset=utf8mb4&time_zone=UTC", pool_pre_ping=True, pool_recycle=40 )另外,你可以在DBeaver里执行
SELECT @@sql_mode, @@time_zone, @@character_set_connection;,然后在SQLAlchemy里也执行同样的查询,对比两者的配置是否一致——很多时候DBeaver会默认带上一些会话配置,而SQLAlchemy的连接没有,这就会导致查询行为不同。修改查询逻辑,避免隐式类型转换
因为你现在是拿text类型的字符串和DATE类型的结果比较,MariaDB的隐式转换规则可能在不同会话下有差异,不如把两边都转成字符串来比较,这样逻辑更明确:SELECT id, Date1 FROM example_table WHERE Date1 != DATE_FORMAT(STR_TO_DATE(Date1, '%Y-%m-%d'), '%Y-%m-%d')或者直接用字符串截取来对比,因为你的Date1格式是
YYYY-MM-DD HH:MM:SS-XX,前10位就是日期部分,所以可以这样写:SELECT id, Date1 FROM example_table WHERE Date1 != LEFT(Date1, 10)这种纯字符串操作的逻辑,不会受类型转换的影响,在DBeaver和SQLAlchemy里的结果应该一致。
检查驱动版本和连接参数
你用的是mariadb+mariadbconnector驱动,确保你的mariadb-connector-python版本是最新的,旧版本可能有一些兼容性问题。另外,pool_pre_ping和pool_recycle参数是连接池相关的,和查询结果关系不大,但可以暂时去掉这些参数,测试下是否是连接池的问题。
备注:内容来源于stack exchange,提问作者clarktwain

