使用ibis.to_sql()转换Ibis为SQL未获预期结果求助
问题
期望生成的SQL语句:
SELECT u.name, nicknames AS nickname FROM `india.nvidia.user_table` u, UNNEST(nicknames) AS nicknames WHERE u.l is true
但使用以下Python代码通过ibis.to_sql()转换后,无法得到匹配的结果:
import ibis region='india' account='nvidia' # Create a dummy table user_profile = ibis.table({ 'name': 'string', 'nicknames':'array<string>', 'l': 'boolean' }, name=f'{region}.{account}.user_table') unnested = user_profile.mutate(nickname=user_profile.nicknames.unnest()) filtered = unnested[unnested.l == True] result = filtered[['name','nickname']] print(ibis.to_sql(result))
解决方案
原代码用mutate+unnest的写法会让Ibis生成将UNNEST嵌入SELECT字段或显式CROSS JOIN的SQL,要得到你期望的FROM子句逗号分隔的隐式交叉连接语法,需要调整写法:
写法一:显式交叉连接UNNEST表
import ibis region='india' account='nvidia' # 定义表结构 user_profile = ibis.table({ 'name': 'string', 'nicknames':'array<string>', 'l': 'boolean' }, name=f'{region}.{account}.user_table') # 生成UNNEST表并与原表交叉连接 unnest_table = user_profile.nicknames.unnest().name('nicknames') joined = user_profile.cross_join(unnest_table) # 过滤并重命名字段 filtered = joined[joined.l == True] result = filtered[['name', 'nicknames']].rename(nicknames='nickname') # 输出目标SQL print(ibis.to_sql(result))
写法二:直接在FROM子句中包含UNNEST
import ibis region='india' account='nvidia' user_profile = ibis.table({ 'name': 'string', 'nicknames':'array<string>', 'l': 'boolean' }, name=f'{region}.{account}.user_table') # 直接构造包含UNNEST的查询 query = ibis.select( user_profile.name, ibis._.nicknames.name('nickname') ).from_( user_profile, user_profile.nicknames.unnest().name('nicknames') ).where(user_profile.l == True) print(ibis.to_sql(query))
说明
- 原写法的
mutate(nickname=user_profile.nicknames.unnest())会让Ibis将UNNEST逻辑放在SELECT字段中,或是生成显式CROSS JOIN UNNEST(...)的语法,不符合目标格式。 - 改用
from_方法同时传入原表和UNNEST生成的表,或是用cross_join,Ibis会生成逗号分隔的隐式交叉连接SQL结构。 - 通过
rename将UNNEST的字段名改为nickname,完全匹配你期望的输出。
内容的提问来源于stack exchange,提问作者numblebee
相关产品推荐
相关产品推荐

