⌘+k ctrl+k
1.1.3 (stable)
Search Shortcut cmd + k | ctrl + k
Conversion between DuckDB and Python

本页面记录了将Python对象转换为DuckDB以及将DuckDB结果转换为Python的规则。

对象转换:Python 对象到 DuckDB

这是Python对象类型到DuckDB 逻辑类型的映射:

  • NoneNULL
  • boolBOOLEAN
  • datetime.timedeltaINTERVAL
  • strVARCHAR
  • bytearrayBLOB
  • memoryviewBLOB
  • decimal.DecimalDECIMAL / DOUBLE
  • uuid.UUIDUUID

其余的转换规则如下。

int

由于在Python中整数可以是任意大小的,因此对于整数来说没有一对一的转换可能。 相反,我们按顺序执行这些转换,直到其中一个成功:

  • BIGINT
  • INTEGER
  • UBIGINT
  • UINTEGER
  • DOUBLE

使用DuckDB Value类时,可以设置目标类型,这将影响转换。

float

这些转换按顺序尝试,直到一个成功:

  • DOUBLE
  • FLOAT

datetime.datetime

对于datetime,我们将检查pandas.isnull是否可用,如果返回true,则返回NULL。 我们检查datetime.datetime.mindatetime.datetime.max以分别转换为-inf+inf

如果 datetime 有 tzinfo,我们将使用 TIMESTAMPTZ,否则它将变为 TIMESTAMP

datetime.time

如果time有tzinfo,我们将使用TIMETZ,否则它将变为TIME

datetime.date

date 转换为 DATE 类型。 我们检查 datetime.date.mindatetime.date.max 以分别转换为 -inf+inf

bytes

bytes 默认转换为 BLOB,当它用于构造类型为 BITSTRING 的 Value 对象时,它映射到 BITSTRING

list

list 成为其子元素“最宽松”类型的 LIST 类型,例如:

my_list_value = [
    12345,
    "test"
]

将变为 VARCHAR[] 因为 12345 可以转换为 VARCHARtest 不能转换为 INTEGER

[12345, test]

dict

dict 对象可以根据其结构转换为 STRUCT(...)MAP(..., ...)。 如果字典的结构类似于:

my_map_dict = {
    "key": [
        1, 2, 3
    ],
    "value": [
        "one", "two", "three"
    ]
}

然后我们将它转换为两个列表压缩在一起的键值对的MAP。 上面的例子变成了一个MAP(INTEGER, VARCHAR)

{1=one, 2=two, 3=three}

字段的名称很重要,两个列表需要具有相同的大小。

否则我们将尝试将其转换为STRUCT

my_struct_dict = {
    1: "one",
    "2": 2,
    "three": [1, 2, 3],
    False: True
}

变为:

{'1': one, '2': 2, 'three': [1, 2, 3], 'False': true}

字典的每个 key 都被转换为字符串。

tuple

tuple 默认转换为 LIST,当它用于构造类型为 STRUCT 的 Value 对象时,它将转换为 STRUCT

numpy.ndarraynumpy.datetime64

ndarraydatetime64 通过调用 tolist() 并转换其结果来进行转换。

结果转换:DuckDB 结果到 Python

DuckDB的Python客户端提供了多种额外的方法,可以用于高效地检索数据。

NumPy

  • fetchnumpy() 将数据作为NumPy数组的字典获取

Pandas

  • df() 将数据作为 Pandas DataFrame 获取
  • fetchdf()df() 的别名
  • fetch_df()df() 的别名
  • fetch_df_chunk(vector_multiple) 将部分结果提取到DataFrame中。每个块返回的行数是向量大小(默认为2048)乘以vector_multiple(默认为1)。

Apache Arrow

  • arrow() 将数据作为 Arrow 表 获取
  • fetch_arrow_table()arrow() 的别名
  • fetch_record_batch(chunk_size) 返回一个 Arrow 记录批次读取器,每批次包含 chunk_size

Polars

  • pl() 将数据获取为 Polars DataFrame

Examples

以下是一些使用此功能的示例。更多示例请参见Python指南

获取为Pandas DataFrame:

df = con.execute("SELECT * FROM items").fetchdf()
print(df)
       item   value  count
0     jeans    20.0      1
1    hammer    42.2      2
2    laptop  2000.0      1
3  chainsaw   500.0     10
4    iphone   300.0      2

以NumPy数组的字典形式获取:

arr = con.execute("SELECT * FROM items").fetchnumpy()
print(arr)
{'item': masked_array(data=['jeans', 'hammer', 'laptop', 'chainsaw', 'iphone'],
             mask=[False, False, False, False, False],
       fill_value='?',
            dtype=object), 'value': masked_array(data=[20.0, 42.2, 2000.0, 500.0, 300.0],
             mask=[False, False, False, False, False],
       fill_value=1e+20), 'count': masked_array(data=[1, 2, 1, 10, 2],
             mask=[False, False, False, False, False],
       fill_value=999999,
            dtype=int32)}

获取为Arrow表。之后转换为Pandas仅用于美观打印:

tbl = con.execute("SELECT * FROM items").fetch_arrow_table()
print(tbl.to_pandas())
       item    value  count
0     jeans    20.00      1
1    hammer    42.20      2
2    laptop  2000.00      1
3  chainsaw   500.00     10
4    iphone   300.00      2