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

Python中如何将字符串/字节CSV数据直接写入DuckDB数据库文件?

直接将内存中CSV数据写入DuckDB文件数据库(免临时文件)

问题场景

需要将内存中bytes/字符串形式的CSV数据直接写入DuckDB本地文件数据库,避免生成临时CSV文件中转。现有尝试代码如下:

import io 
import duckdb 

data = b'a,b,c\n0,1,2\n3,4,5'
rawtbl = duckdb.read_csv(
    io.BytesIO(data), header=True, sep=","
)

con = duckdb.connect('some.db')
con.sql('CREATE TABLE foo AS SELECT * FROM rawtbl')

运行后抛出异常:

---------------------------------------------------------------------------
IOException                               Traceback (most recent call last)
Cell In[1], line 10
      5 rawtbl = duckdb.read_csv(
      6     io.BytesIO(data), header=True, sep=","
      7 )
      9 con = duckdb.connect('some.db')
---> 10 con.sql('CREATE TABLE foo AS SELECT * FROM rawtbl')

IOException: IO Error: No files found that match the pattern "DUCKDB_INTERNAL_OBJECTSTORE://2843be5a66472f9c"

但直接在内存数据库中执行duckdb.sql('CREATE TABLE foo AS SELECT * FROM rawtbl')是可行的——因为rawtbl属于内存会话的DuckDBPyRelation对象,无法跨会话被文件连接引用。

错误原因

duckdb.read_csv()默认使用内存中的DuckDB会话,而duckdb.connect('some.db')创建的是独立的文件数据库会话,两个会话完全隔离,文件连接无法识别内存会话中的rawtbl对象,因此报错。

解决方案

方法一:在文件连接上下文内读取内存CSV

直接通过文件连接调用read_csv(),生成的关系对象属于该文件会话,可直接用于建表:

import io 
import duckdb 

data = b'a,b,c\n0,1,2\n3,4,5'

# 建立文件数据库连接
con = duckdb.connect('some.db')
# 直接在文件连接中读取内存CSV数据
csv_relation = con.read_csv(io.BytesIO(data), header=True, sep=",")
# 创建表
con.sql('CREATE TABLE foo AS SELECT * FROM csv_relation')

# 验证结果
print(con.sql('SELECT * FROM foo'))
# 关闭连接
con.close()

方法二:注册内存对象后用SQL读取

将内存中的BytesIO对象注册到文件连接中,再通过SQL的read_csv()读取:

import io 
import duckdb 

data = b'a,b,c\n0,1,2\n3,4,5'

con = duckdb.connect('some.db')
# 把内存BytesIO注册为文件连接可识别的对象
con.register('memory_csv', io.BytesIO(data))
# 通过SQL读取注册的对象并创建表
con.sql('CREATE TABLE foo AS SELECT * FROM read_csv(\'memory_csv\', header=True, sep=\',\')')

print(con.sql('SELECT * FROM foo'))
con.close()

方法三:迁移内存关系到文件数据库

如果已经在内存会话中生成了DuckDBPyRelation,可以通过参数绑定的方式将其导入文件连接:

import io 
import duckdb 

data = b'a,b,c\n0,1,2\n3,4,5'
# 内存会话中生成关系对象
rawtbl = duckdb.read_csv(io.BytesIO(data), header=True, sep=",")

con = duckdb.connect('some.db')
# 通过参数绑定将内存关系导入文件数据库并建表
con.execute('CREATE TABLE foo AS SELECT * FROM ?', [rawtbl])

print(con.sql('SELECT * FROM foo'))
con.close()

推荐方案

优先选择方法一,所有操作都在文件连接上下文内完成,逻辑最直接,避免跨会话的对象引用问题,性能也最优。

内容的提问来源于stack exchange,提问作者Niko Fohr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:08:18