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。
安装步骤
-
安装 Python 环境。
-
添加 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" -
在 DolphinDB 客户端中使用
listRemotePlugins命令查看插件仓库中的插件信息。login("admin", "123456") listRemotePlugins() -
使用
installPlugin命令完成插件安装。根据 Python 环境选择安装对应的插件,支持 py39, py310, py311, py312 及 py313。
例如,Python 3.9 环境选择安装 py39 插件。
installPlugin("py39") -
使用
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 |
