SQLAlchemy Core查询information_schema无结果,是否存在限制?
问题分析与解决方案
这大概率不是SQLAlchemy的限制,而是PostgreSQL标识符处理的细节坑——我之前也踩过类似的雷,主要是大小写敏感性或者schema匹配的问题,帮你拆解下:
1. 最常见的原因:标识符大小写不匹配
PostgreSQL默认会把未加双引号的标识符(表名、列名等)自动转成小写存储,但如果你的表是创建时带双引号的(比如CREATE TABLE "myTable" (...)),那么它在information_schema里的存储名称就是带大小写的"myTable",而非小写的mytable。
- 在psql/DataGrip里,你输入的
myTable可能被客户端自动处理了引号;但SQLAlchemy执行原始SQL字符串时,ccu.table_name = 'myTable'会被当作匹配小写的mytable,自然查不到结果。
解决方法:
把表名用双引号包裹,在SQL字符串里转义双引号,或者用参数化查询更优雅安全:
# 方法1:直接转义双引号 req = ''' SELECT tc.constraint_name, tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_name = '"myTable"' ''' # 方法2:参数化查询(更推荐,避免SQL注入+自动适配标识符规则) from sqlalchemy import text req = text(''' SELECT tc.constraint_name, tc.table_name, kcu.column_name, ccu.table_name AS foreign_table_name, ccu.column_name AS foreign_column_name FROM information_schema.table_constraints AS tc JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_name = :table_name ''') result = con.execute(req, table_name='myTable') rows = result.fetchall()
2. 容易忽略的点:Schema不匹配
如果myTable不在PostgreSQL默认的public schema下,你需要在查询里指定table_schema条件,否则information_schema只会搜索当前连接的默认schema:
WHERE constraint_type = 'FOREIGN KEY' AND ccu.table_schema = 'your_target_schema' -- 加上这行指定schema AND ccu.table_name = 'myTable'
psql/DataGrip可能已经帮你设置了search_path包含目标schema,所以能查到,但SQLAlchemy的连接默认可能只指向public,导致结果为空。
3. 快速验证步骤
先执行一个简单查询确认表的真实存储信息:
check_query = text("SELECT table_name, table_schema FROM information_schema.tables WHERE table_name LIKE '%myTable%'") check_result = con.execute(check_query).fetchall() print(check_result)
从结果里你能看到表名的真实大小写和所属schema,再针对性调整原查询即可。
内容的提问来源于stack exchange,提问作者Rémi Desgrange
相关产品推荐
相关产品推荐

