Py(3.9 及以上版本)

新 py 插件支持在 DolphinDB 中通过面向对象风格的接口调用 Python 包及各种函数。目前,新 py 插件支持 Python 3.9-3.13,并提供对应的版本:py39, py310, py311, py312 及 py313。用户可根据 Python 版本选择相应插件。本插件仅提供必要或常用的函数调用相关接口,不支持 Python 的特殊语法。

新插件基于 DolphinDB 3.x 重新设计了接口与实现机制,与旧版 py 插件不兼容,无法直接升级。新版在降低使用难度的同时,将旧插件中部分隐式处理逻辑改为显式控制,使类型转换等操作更加清晰可控。

本插件不提供任何 Python 相关的程序(包括 Python 解释器与第三方库),所有 Python 程序均由用户环境提供。在插件运行时,第三方库会加载到 DolphinDB 进程中,可能引发兼容性问题。因此,在生产环境部署前,务必完成充分的兼容性测试。

安装插件

版本要求

DolphinDB server: 3.00.3 及更高版本。支持 Linux x64。

注:

DolphinDB 3.00.3 以前版本自带的 OpenSSL 与大量第三方库冲突,建议使用 3.00.4 及以上版本。

Python 官方已停止支持 Python 3.8,建议使用 3.9 及以上版本。关键依赖库版本如下表所示,推荐使用相同版本。

Python 版本 numpy 版本 pandas 版本
3.13 2.3.1 2.3.1
3.9-3.12 2.0.1 2.3.1

最低版本要求:Python >= 3.9,numpy >= 2.0,pandas >= 2.0。

安装步骤

  1. 安装 Python 环境。

  2. 添加 globalDynamicLib 参数。如果是单节点模式,则在 dolphindb.cfg 中配置该参数;如果是集群模式,则在 cluster.cfg 中配置该参数。

    globalDynamicLib=/path_to_libpython3.so/libpython3.so

    注: 可使用以下方式查找该路径。

    # 使用 conda 虚拟环境时
    realpath $(dirname $(which python3))/../lib/libpython3.so
    # 使用 uv 虚拟环境时
    realpath $(dirname $(realpath -P $(which python3)))/../lib/libpython3.so
    # 使用系统 python 时
    find /usr/ -name "libpython3*.so"
  3. 在 DolphinDB 客户端中使用 listRemotePlugins 命令查看插件仓库中的插件信息。

    login("admin", "123456")
    listRemotePlugins()
  4. 使用 installPlugin 命令完成插件安装。

    根据 Python 环境选择安装对应的插件,支持 py39, py310, py311, py312 及 py313。

    例如,Python 3.9 环境选择安装 py39 插件。

    installPlugin("py39")
  5. 使用 loadPlugin 命令加载插件。

    // 加载对应版本的插件,例如加载 py39 插件
    loadPlugin("py39")

当使用 Anaconda 时,由于其包含的 libstdc++.so.6 动态库版本较新,可能与 DolphinDB 使用的旧版本不兼容。为避免版本冲突,建议按以下方法操作:

方法一:

重装需要链接到 libstdc++.so.6 的模块,以 pandas 为例:

  • 使用 pip uninstall pandas 命令卸载当前版本的 pandas。

  • 使用 pip install pandas 命令重新安装 pandas。

注:

避免使用 conda install 命令安装 pandas,因为这可能会链接到较新版本的libstdc++.so.6,导致插件加载失败。

方法二:

可尝试将 Anaconda 的 lib 目录下的 libstdc++.so.6 文件复制到 DolphinDB 的相应目录下(为了防止意外,请先备份原有的 libstdc++.so.6 文件)。此方法无需重装模块。

在 DolphinDB 中表示 Python 对象

DolphinDB 支持面向对象编程,允许用户自定义类并实例化其对象。本插件内部定义了 PythonClass 类用于封装 py::object。

由于 Python 插件并不会修改 DolphinDB 脚本解释器,因此对 Python 对象的操作受限于 Dlang 本身的表达能力。

接口说明

注:
  • Python 没有特定类型的空值,因此不支持对 DolphinDB 的 NULL 值进行转换。

  • 接口选择应根据后续使用需求,而不是 DolphinDB 类型。例如,某数据后续用作第三方库接口参数,接口需要 numpy 类型,此时应当选择 toNumpy

  • 在没有合适的数据类型的情况下,转换可能损失信息。例如,纳秒精度的时间类型在 Python 中没有对应类型,会被转换为整数,因此 py:fromPy(py::toPy(x)) 与 x 不等价。

setGlobalConfig

语法

py::setGlobalConfig(key, value)

详情

设置全局配置。

参数

  • key STRING 类型标量,表示配置项的名称。目前支持配置项 "autoConvert",表示调用 Python 函数且参数是 DolphinDB 对象时是否进行类型转换,默认值为 false。

  • value 表示该配置项的值,其数据类型与配置项有关。

调用 Python 函数时,参数是 DolphinDB 对象:

  • autoConvert = true,则会将 DolphinDB 数据类型转换为 Python 数据类型。

  • autoConvert = false,则会报错。

// 配置 autoConvert
py::setGlobalConfig("autoConvert", true);
// 或
py::setGlobalConfig("autoConvert", false);

/* Python file: example.py
def add(a):
    return a + 2
*/    

// ddb script
example = py::import("example");
res = example.add(5);
// autoConvert = true, 自动将参数 ddb constant 5 转换为 python int 5
// autoConvert = false, 会报错(若实现了装箱,则会将ddb constant 5装箱后传入函数)
注:

为使 Python 接口构造的对象能够用于 Python 函数调用,autoConvert 不会转换返回值。

import

语法

py::import(module)

详情

引入 Python 模块,并返回一个 DolphinDB 对象。

参数

module STRING 类型标量,表示需要引入的模块名。

例子

np = py::import("numpy");

int

语法

py::int(value)

详情

构造 Python int 对象并返回一个 DolphinDB 对象。

参数

value 标量,表示初始值,必须可以转换为 LONG 类型。

例子

py::int(1)

float

语法

py::float(value)

详情

构造 Python float 对象并返回一个 DolphinDB 对象。

参数

value 标量,表示初始值,必须可以转换为 DOUBLE 类型。

例子

py::float(1.1)

bool

语法

py::bool(value)

详情

构造 Python bool 对象并返回一个 DolphinDB 对象。

参数

value 标量,表示初始值,必须可以转换为 BOOL 类型。

例子

py::bool(true)

str

语法

py::str(value)

详情

构造 Python str 对象并返回一个 DolphinDB 对象。

参数

value 标量,表示初始值。必须可以转换为 UTF8 格式的 STRING 类型。

例子

py::str("123")

bytes

语法

py::bytes(value)

详情

构造 Python bytes 并返回一个 DolphinDB 对象。

参数

value 标量,表示初始值,必须可以转换为 STRING 类型。

例子

py::bytes("123")

list

语法

py::list(data)

详情

构造 Python list 并返回一个 DolphinDB 对象。

参数

data 向量或元组,表示初始值。

例子

py::list(1 2 3)

tuple

语法

py::tuple(data)

详情

构造 Python tuple 并返回一个 DolphinDB 对象。

参数

data 向量或元组,表示初始值。

例子

py::tuple(1 2 3)

set

语法

py::set(data)

详情

构造 Python set 并返回一个 DolphinDB 对象。

参数

data 向量、元组或集合,表示初始值。

例子

py::set(1 2 3)

dict

语法

py::dict(data)

py::dict(keys, values)

详情

构造 Python dict 并返回一个 DolphinDB 对象。

参数

data 向量,表示初始值。

keys 向量,表示字典的键的初始值。

values 向量,表示字典的值的初始值。

例子

py::dict({1: 2, 3: 4, 5: 6})
py::dict(1 2 3, 4 5 6)

toPy

语法

py::toPy(data)

详情

将 DolphinDB 对象转为对应的 Python 对象,并返回 Python 对象。

注:

由于旧 py 插件的 toPy 接口会自动选择转换为 Python、pandas 或 numpy,因此新 py 插件的 toPy 接口与旧 py 插件的 toPy 接口不兼容。

参数

data 表示被转换的数据。

例子

x = 1
y = py::toPy(x)

x = 1 2 3 4
y = py::toPy(x)

x = dict(1 2 3, 4 5 6)
y = py::toPy(x)

x = set(1 2)
y = py::toPy(x)

x = 1:2
y = py::toPy(x) // DolphinDB pair -> Python list

x = table(1 2 3 as a, `x`y`z as b)
y = py::toPy(x) // DolphinDB table -> Python dict

fromPy

语法

py::fromPy(data)

详情

将 Python 对象转为对应的 DolphinDB 对象,并返回 DolphinDB 对象。

参数

data 表示被转换的数据。

例子

x = 1
y = py::fromPy(py::toPy(x))

x = 1 2 3 4
y = py::fromPy(py::toPy(x))

x = dict(1 2 3, 4 5 6)
y = py::fromPy(py::toPy(x))

x = set(1 2)
y = py::fromPy(py::toPy(x))

x = 1:2
y = py::fromPy(py::toPy(x)) // DolphinDB pair <-> python list

x = table(1 2 3 as a, `x`y`z as b)
y = py::fromPy(py::toPy(x)) // DolphinDB table <-> python dict

toPandas

语法

py::toPandas(data)

详情

将 DolphinDB 对象转为对应的 pandas 对象,并返回 pandas 对象。

参数

data 表示被转换的数据。

例子

x = 1 2 3 4
y = py::toPandas(x) // pandas Series
x = table(1 2 3 as a, `x`y`z as b)
y = py::toPandas(x) // pandas DataFrame

fromPandas

语法

py::fromPandas(data)

详情

将 pandas 对象转为对应的 DolphinDB 对象,并返回 DolphinDB 对象。

参数

data 表示被转换的数据。

例子

x = 1 2 3 4
y = py::fromPandas(py::toPandas(x)) // pandas Series

x = table(1 2 3 as a, `x`y`z as b)
y = py::fromPandas(py::toPandas(x)) // pandas DataFrame

toNumpy

语法

py::toNumpy(data)

详情

将 DolphinDB 对象转为对应的 numpy 对象,并返回 numpy 对象。

参数

data 表示被转换的数据。

例子

x = 1 2 3 4
y = py::toNumpy(x) // numpy ndarray

x = matrix(1 2 3, 4 5 6)
y = py::toNumpy(x) // numpy ndarray

fromNumpy

语法

py::fromNumpy(data)

详情

将 numpy 对象转为对应的 DolphinDB 对象,并返回 DolphinDB 对象。

参数

data 表示被转换的数据。

例子

x = 1 2 3 4
y = py::fromNumpy(py::toNumpy(x)) // numpy ndarray

x = matrix(1 2 3, 4 5 6)
y = py::fromNumpy(py::toNumpy(x)) // numpy ndarray

call

语法

py::call(object, [functionName], [args...])

详情

用于调用 Python 方法。

参数

object 标量,表示 Python 对象。

functionName 可选参数,STRING 类型标量,表示方法名。若为空,则将 object 作为可调用对象进行调用。

args... 可选参数,可变数量的参数,表示 functionName 指定的 Python 方法的参数。

例子

np = py::import("numpy")
x = py::call(np, "add", py::int(1), py::int(2))
print(x) // np.int64(3)

a = py::call(np, "array", py::toPy(1 2 3))
y = py::call(a, "sum")
print(y) // np.int64(6)

type

语法

py::type(data)

详情

获取 Python 对象的属性和方法列表。通过访问 Python 对象的 __class__ 属性,返回该对象所属类的类型信息。

参数

data 表示要获取类型信息的 Python 对象。

例子

os = py::import("os");
cwd = os.getcwd();
py::type(cwd);
// Output: <class 'str'>

datetime = py::import("datetime");
dt = datetime.date.today();
py::type(dt);
// Output: <class 'datetime.date'>

dir

语法

py::dir(data)

详情

获取 Python 对象的属性和方法列表。通过调用 Python 内置的 dir() 函数,返回一个包含对象所有属性和方法名的列表。

参数

data 表示要获取属性和方法列表的 Python 对象。

例子

math = py::import("math");
py::dir(math);
// output: ["__doc__","__file__","__loader__","__name__","__package__","__spec__","acos","acosh","asin","asinh","atan","atan2","atanh","ceil","copysign","cos","cosh","degrees","e","erf","erfc","exp","expm1","fabs","factorial","floor","fmod","frexp","fsum","gamma"...]

使用示例

示例1:调用 Python 代码

下面以一个 Python 对象为例,演示如何在 DolphinDB 中使用新 py 插件来调用 Python 代码:

假设 Python 代码(example.py)如下:

class Example:
    def __init__(self, a):
        self.a = a
    def myMethod(self, b):
        self.a += b
    def __str__(self):
        return f"Example({self.a})"
def myFunc(a, b):
    return a + b + 1;
def add(a, b):
    return a + b + 1;

1、导入 example 包

example = py::import("example")

2、查看 example 包提供的接口

可以看到 example 提供的 Example 类与 myFunc 函数。

py::dir(example)
// 示例输出(string 向量):
// Example	__builtins__ ... __name__ __package__ __spec__ myFunc

3、调用 Python 函数

example 方法(构造函数)与 DolphinDB 中的内置函数不冲突,可以通过面向对象语法调用。

myexample = example.Example(py::int(1));

可以像内置变量一样查看或打印 Python 对象。

myexample // 调用 __repr__ 显示 '<example.Example object at 0x72992708b5f0>'
print(myexample) // 调用 __str__ 显示 Example(1)
注:

对于 Python 中的内置函数,当前插件仅支持位置参数调用,不支持关键字参数,例如:numpy.array(py::list(1..10))。若需指定关键字参数,建议通过自定义 Python 模块实现。

4、调用成员方法

与调用 Python 包的方法类似。

myexample.myMethod(py::toPy(1)) // 返回 None
注:

如果 python 接口与 DolphinDB 内置函数重名,则无法按照上述方式调用,需要使用 py::call 接口

example.add(py::int(1), py::int(2)) // add(example, py::py::int(1), py::py::int(2)) => The function [add] expects 2 argument(s), but the actual number of arguments is: 3

py::call(example, "add", py::int(1), py::int(2)) '4'

5、读取类成员

可以通过 . 来读取类成员。

myexample.a // 1

示例2:调用 lightGBM

lgbm = py::import("lightgbm")
py::setGlobalConfig("autoConvert", true)

x1 = take([381.46, 3328.129, 676.567, 0, 4626.67, 1617.26, -2987.77, -114.51, -514.11, 1365.48], 100)
x2 = take([5290.34, -8721.55, 0.00, 445.67, -1599.28, 3820.45, 713.12, -64.32, 9021.78, -120.50], 100)
x3 = take([-332.40, 7564.89, -9999.99, 0.00, 482.30, -541.11, 6283.45, -789.25, 2500.60, 87.65], 100)
x4 = take([0.00, -253.77, 643.25, 8120.40, -7100.55, 9999.99, -86.34, 570.90, -3250.70, 152.20], 100)
x5 = take([-25.40, 0.00, -6842.22, 3011.35, 129.55, -918.30, 4200.42, -77.77, 8654.10, -5000.00], 100)
X = py::toPandas(table(x1, x2, x3, x4, x5))
Y = take([10, 514, 6342, 7830, 102, 9821, 471, 600, 9999, 2100], 100)
pyData = py::call(lgbm, "Dataset", X, Y)
ex = take([81.856452, 503.020383, 6346.165492, 7835.093430, 240.526336, 9041.394067, 5198.338019, 628.218282, 5297.480024, 2140.621803], 100)
params = {
	'objective': 'regression_l1',
	'boosting': 'gbdt',
	'learning_rate': 0.1,
	'min_data_in_leaf': 20,
	'verbose': -1
}
pyModel = py::call(lgbm, "train", params, pyData, 100)
re = py::fromPy(py::call(pyModel, "predict", X))
assert 1, eqObj(re, ex, 5)

示例3:调用 pytorch

代码需使用 1D_model.pth 模型,请先下载该文件。

fin=file("/home/dolphindb/test_predict.py","w+");
fin.writeLine("
import torch
import torch.nn as nn
 
def read_predict(input, path):
    model = torch.load(path, weights_only=False)
    x_test = torch.tensor(input)
    y_test = model(x_test)
    return y_test
");
fin.close()

tc = py::import("torch")
sv = py::import("test_predict")

input_input_tensor = py::call(tc, "tensor", py::list([1.1]))
res = py::call(sv, "read_predict", py::list([1.1]), py::str(DATA_DIR+"/LibTorch/1D_model.pth"))

示例4:调用 tensorflow

运行代码前,请先下载:saved_models.zip

np = py::import("numpy")
keras_models = py::import("tensorflow.keras.models")
// load model
loaded_model_h5 = py::call(keras_models, "load_model", py::str(DATA_DIR+"/saved_models/classification_model.h5"))

a1 = py::list(1.5 1.5)
a2 = py::list(0.5 0.5)
a3 = py::list(-1.2 -1.2)
a4 = py::list(0.3 0.3)
a5 = py::list(2.0 0.0)

a = py::list([a1, a2, a3, a4, a5])
new_test_data = py::call(np, "array", a)

predictions = py::call(loaded_model_h5, "predict", new_test_data)

re = py::fromPy(predictions)

示例5:调用 xgboost

mtx = matrix(table(1..5 as c1, 1..5 * 2 as c2, 1..5 * 3 as c3))
label = rand([true, false], 5)
dtrain = xgb.DMatrix(mtx, label)

x = ["max_depth", "eta", "objective", "eval_metric"]
y = [2, 1, "binary:logistic", ["error", "auc"]]
param=dict(string(x), y)
model = xgb.train(param, dtrain, 1)

res = py::call(model, "predict", dtrain)
res = py::fromPy(res)
py::setGlobalConfig("autoConvert", true)
xgb = py::import("xgboost")

dtrain = xgb.DMatrix(
	py::call(os.path, "abspath", DATA_DIR+"/agaricus.txt.train?format=libsvm")
)
dtest = xgb.DMatrix(
	py::call(os.path, "abspath", DATA_DIR+"/agaricus.txt.test?format=libsvm")
)

x = ["max_depth", "eta", "objective"]
y = [2, 1, "binary:logistic"]
param=dict(string(x), y)

watchlist = py::list([py::tuple((dtest, "eval")), py::tuple((dtrain, "train"))])
num_round = 3
bst = xgb.train(param, dtrain, num_round, watchlist)

print("start testing predict the leaf indices")
leafindex = py::call(bst, "predict", dtest)
assert 1, py::fromPy(leafindex.shape) ==[1611]
leafindex = py::fromPy(leafindex)
assert 2, leafindex.size() == 1611

支持的数据类型

DolphinDB 对象转成 Python 对象

DolphinDB 数据类型 Python 数据类型 Numpy 类型 Pandas 类型
VOID NoneType - -
BOOL bool bool bool
CHAR / SHORT / INT / LONG int int8 / int16 / int32 / int64 int8 / int16 / int32 / int64
FLOAT / DOUBLE float float32 / float64 float32 / float64
STRING / SYMBOL str object object
BLOB bytes object object
DATE / MONTH datetime.date datetime64[D] / datetime64[M] datetime64[s] / datetime64[s]
TIME / MINUTE / SECOND datetime.time datetime64[ms] / datetime64[s] / datetime64[s] datetime64[ms] / datetime64[s] / datetime64[s]
DATETIME / TIMESTAMP / DATEHOUR datetime.datetime datetime64[ms] / datetime64[ms] / datetime64[ms] datetime64[ms] / datetime64[ms] / datetime64[ms]
NANOTIME / NANOTIMESTAMP int datetime64[ns] datetime64[ns]
Decimal32 / Decimal64 / Decimal128 decimal.Decimal object object
注:
  • 向量和矩阵会转换为 numpy.array。

  • MONTH 类型,如 2012.06M,会转换为 2012-06-01(即月份当月的第一天)。

  • 暂不支持转换 INT128 / UUID / IPADDR / POINT / FUNCTIONDEF / CODE / HANDLE / DURATION 类型。

Python 对象转成 DolphinDB 对象

Python 数据类型 DolphinDB 数据类型
bool BOOL
int LONG
float DOUBLE
str STRING
bytes BLOB
decimal.Decimal DECIMAL128
datetime.datetime DATETIME
datetime.date DATE
datetime.time TIME
datetime64[D] DATE
datetime64[M] MONTH
datetime64[m] / datetime64[s] DATETIME
datetime64[h] DATEHOUR
datetime64[ms] TIMESTAMP
datetime64[us] / datetime64[ns] NANOTIMESTAMP
datetime64 NANOTIMESTAMP
np.bool BOOL
np.int8 CHAR
np.int16 SHORT
np.int32 INT
np.int64 LONG
np.float32 FLOAT
np.float64 DOUBLE
np.str_ STRING
pd.NA NULL
pd.NaT NANOTIMESTAMP(NULL)
pd.Timestamp NANOTIMESTAMP