本页面记录了将Python对象转换为DuckDB以及将DuckDB结果转换为Python的规则。
对象转换:Python 对象到 DuckDB
这是Python对象类型到DuckDB 逻辑类型的映射:
None
→NULL
bool
→BOOLEAN
datetime.timedelta
→INTERVAL
str
→VARCHAR
bytearray
→BLOB
memoryview
→BLOB
decimal.Decimal
→DECIMAL
/DOUBLE
uuid.UUID
→UUID
其余的转换规则如下。
int
由于在Python中整数可以是任意大小的,因此对于整数来说没有一对一的转换可能。 相反,我们按顺序执行这些转换,直到其中一个成功:
BIGINT
INTEGER
UBIGINT
UINTEGER
DOUBLE
使用DuckDB Value类时,可以设置目标类型,这将影响转换。
float
这些转换按顺序尝试,直到一个成功:
DOUBLE
FLOAT
datetime.datetime
对于datetime
,我们将检查pandas.isnull
是否可用,如果返回true
,则返回NULL
。
我们检查datetime.datetime.min
和datetime.datetime.max
以分别转换为-inf
和+inf
。
如果 datetime
有 tzinfo,我们将使用 TIMESTAMPTZ
,否则它将变为 TIMESTAMP
。
datetime.time
如果time
有tzinfo,我们将使用TIMETZ
,否则它将变为TIME
。
datetime.date
date
转换为 DATE
类型。
我们检查 datetime.date.min
和 datetime.date.max
以分别转换为 -inf
和 +inf
。
bytes
bytes
默认转换为 BLOB
,当它用于构造类型为 BITSTRING
的 Value 对象时,它映射到 BITSTRING
。
list
list
成为其子元素“最宽松”类型的 LIST
类型,例如:
my_list_value = [
12345,
"test"
]
将变为 VARCHAR[]
因为 12345 可以转换为 VARCHAR
但 test
不能转换为 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.ndarray
和 numpy.datetime64
ndarray
和 datetime64
通过调用 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