You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nixpkgs中如何让Python包duckdb使用Overlay修改后的DuckDB?

问题:Python版DuckDB未使用Overlay修改后的版本

我使用如下Flake配置:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  }:
    flake-utils.lib.eachDefaultSystem
    (
      system: let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [
            (final: prev: {
              duckdb = prev.duckdb.overrideDerivation(old: {
                cmakeFlags = old.cmakeFlags ++ ["-DSKIP_EXTENSIONS=jemalloc"];
              });
            })
          ];
        };
        python = pkgs.python311;
        buildInputs = with pkgs; [
          (python.withPackages (ps:
            with ps; [
              duckdb
            ]))
          duckdb

        ];
      in
        with pkgs; {
          devShells.default = mkShell {
            inherit buildInputs;
          };
        }
    );
}

我成功构建了不含jemalloc的DuckDB,通过命令行测试:

echo "SELECT installed FROM duckdb_extensions() WHERE extension_name='jemalloc';" | duckdb

返回false,符合预期。但Python包python3Packages.duckdb仍使用未修改前的DuckDB版本,执行以下测试代码失败:

import duckdb
assert not duckdb.connect().execute("SELECT installed FROM duckdb_extensions() WHERE extension_name='jemalloc';").fetchone()[0]

我本以为Overlay会作用于整个pkgs集合,使pkgs.python311.duckdb使用修改后的DuckDB,但实际并非如此。请问正确的实现方式是什么?我对Overlay的理解存在哪些误区?


误区分析

你对Overlay的核心误区在于:Python包集合(比如python311.pkgs)是独立于顶层pkgs的衍生集合,顶层Overlay不会自动渗透到Python的包集合中。

具体来说,pkgs.python311是一个带有自身包集合的Python环境,它的duckdb包是基于Python自身的依赖解析逻辑构建的,默认会使用Python包集合里引用的原始DuckDB,而非顶层pkgs中被Overlay修改后的版本。

正确实现方式

要让Python版DuckDB使用修改后的底层DuckDB,需要在Overlay中同时修改Python包集合里的duckdb,让它依赖顶层修改后的duckdb。修改后的Flake配置如下:

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  }:
    flake-utils.lib.eachDefaultSystem
    (
      system: let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [
            (final: prev: {
              # 1. 修改顶层的DuckDB
              duckdb = prev.duckdb.overrideDerivation(old: {
                cmakeFlags = old.cmakeFlags ++ ["-DSKIP_EXTENSIONS=jemalloc"];
              });
              # 2. 修改Python包集合中的duckdb,让它依赖修改后的顶层duckdb
              python311 = prev.python311.override {
                packageOverrides = pythonFinal: pythonPrev: {
                  duckdb = pythonPrev.duckdb.overridePythonAttrs(old: {
                    propagatedBuildInputs = old.propagatedBuildInputs ++ [final.duckdb];
                    # 强制重新构建,确保链接到新的DuckDB
                    doCheck = false; # 可选,若测试用例依赖jemalloc可临时关闭
                  });
                };
              };
            })
          ];
        };
        python = pkgs.python311;
        buildInputs = with pkgs; [
          (python.withPackages (ps: [ps.duckdb]))
          duckdb
        ];
      in
        with pkgs; {
          devShells.default = mkShell {
            inherit buildInputs;
          };
        }
    );
}

关键修改点:

  • 在顶层Overlay中,通过python311.override给Python环境添加packageOverrides,专门修改Python包集合里的duckdb。
  • 使用overridePythonAttrs覆盖Python版DuckDB的属性,让它依赖顶层修改后的duckdb,确保编译/链接时使用不含jemalloc的版本。
  • 可选关闭doCheck:如果Python版DuckDB的测试用例依赖jemalloc存在,可能需要临时关闭测试以构建成功。

修改后重新进入devShell,运行Python测试代码即可验证断言通过。

内容的提问来源于stack exchange,提问作者2e0byo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:36:05