必须用对应后端的 connect 函数:ibis.duckdb.connect() 用于本地 duckdb,ibis.bigquery.connect() 用于 bigquery;混用会报 notimplementederror 或静默降级;连接后需立即用 con.list_tables() 验证。

用 ibis.duckdb.connect() 还是 ibis.bigquery.connect()?别混着用
不同后端必须用对应 connect 函数初始化连接,ibis.connect("duckdb://") 和 ibis.connect("bigquery://") 表面统一,实则底层完全隔离。混用会导致 NotImplementedError: Operation not supported for backend 或静默降级为 pandas 执行(查不到数据还报错)。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 明确后端类型再选函数:
ibis.duckdb.connect()用于本地 .db 文件或内存 DB;ibis.bigquery.connect()必须配project_id和认证凭据 - 不要依赖
ibis.connect()的自动推断——它对 DuckDB 支持不稳定,BigQuery 则根本不会识别 URL 中的 project 信息 - 连接后立刻验证:
con.list_tables()看是否返回预期表名,避免后续执行时才发现连错库
ibis.table() 加 schema 定义不是可选项
DuckDB 能自动 infer 表结构,BigQuery 不行。不显式传 schema 参数,BigQuery 会报 TypeError: Cannot determine type of column 'xxx',尤其遇到 DATE、TIME、嵌套字段时更敏感。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 定义表时强制加 schema:
t = con.table("my_table", schema={"ts": "timestamp", "user_id": "int64", "meta": "struct<city: string tags: array>>"})</city:> - DuckDB 也建议加——避免因空值列推断成
string,后续 join 或 filter 出现隐式转换失败 - 从 BigQuery 导出 schema 可用
bq show --format=prettyjson project:dataset.table | jq '.schema.fields'快速转成 ibis 字段字典
SQL 生成差异:DuckDB 允许 SELECT *,BigQuery 要求显式列名
ibis.table("t").select("*") 在 DuckDB 下正常生成 SQL,在 BigQuery 下会抛 CompileError: Wildcard not allowed in SELECT list。这不是 ibis bug,是 BigQuery 引擎限制。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 永远避免
.select("*"),改用.select(t)(t 是表对象)或.select(*t.columns) - 如果要动态选列,先
t.columns获取列表,过滤掉不支持的类型(如ARRAY列不能直接参与 GROUP BY)再构造 select - 注意
ibis.coalesce()在 BigQuery 里会生成COALESCE,但 DuckDB 对 NULL 处理更宽松;两边都用ibis.where()替代部分 coalesce 场景更稳
写入行为不一致:DuckDB 支持 .to_parquet(),BigQuery 只能 .execute() + INSERT
t.to_parquet("out.parquet") 在 DuckDB 后端有效,在 BigQuery 后端直接报 AttributeError: 'BigQueryBackend' object has no attribute 'to_parquet'。所有写操作必须走执行路径,且需区分临时表和目标表权限。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 写入逻辑必须分支处理:
if isinstance(con, ibis.backends.duckdb.Backend): t.to_parquet(...);否则用con.create_table("dst", t.execute(), overwrite=True) - BigQuery 写入前确认 dataset 存在且有
bigquery.tables.create权限;DuckDB 写入注意路径权限和磁盘空间 - 大结果集别用
.execute().to_pandas()中转——BigQuery 可能 OOM,DuckDB 则丢精度(timestamp 亚秒级截断);优先用.to_pyarrow()或流式 fetch
跨后端最麻烦的不是语法,而是“看起来一样、执行时才崩”的隐性差异。比如同一段 ibis.date_add() 在 DuckDB 返回 date,在 BigQuery 返回 timestamp,下游 cast 一漏就全错。得把每个函数的返回类型当契约来读,不能只看文档示例。










