如何用Polars结合Psycopg2将列表列写入PostgreSQL的ARRAY类型?
如何将Polars列表列以PostgreSQL ARRAY类型写入数据库
问题分析
你遇到的核心问题有两个:
- 使用
QuotedString适配器会将数组格式的字符串标记为文本类型,即使语法正确也会被存为TEXT列 - 未指定表结构时,Polars会自动将列表列推断为
TEXT类型,导致表结构不符合预期
解决方案
1. 注册正确的psycopg2适配器
替换QuotedString为AsIs,让psycopg2直接识别数组语法为PostgreSQL的ARRAY类型,同时适配Python列表和numpy数组:
import polars as pl def register_psycopg_adapters(): import numpy as np from psycopg2.extensions import register_adapter, AsIs # 适配numpy数组 def addapt_numpy_array(numpy_array): # 转换为PostgreSQL数组格式:[1.0,42.0] → {1.0,42.0} arr_str = np.array2string(numpy_array, separator=',', formatter={'float_kind':lambda x: f"{x}"}) return AsIs(arr_str.replace('[','{').replace(']','}')) # 适配Python列表 def addapt_list(list_obj): return AsIs("{" + ", ".join(map(str, list_obj)) + "}") register_adapter(np.ndarray, addapt_numpy_array) register_adapter(list, addapt_list)
2. 手动指定表结构Schema
在write_database时通过schema参数明确列类型,避免Polars自动推断错误:
def test_writing_array_to_postgres(): conn = "..." # 你的PostgreSQL连接字符串 register_psycopg_adapters() df = pl.DataFrame( dict( foo=[[1.0, 42.0], [4.0, 7.0]], bar=["baz", "qux"], ) ) # 定义表结构:指定foo为REAL[]类型,bar为VARCHAR(24) schema = { "foo": "REAL[]", "bar": "VARCHAR(24)" } df.write_database( "test_arrays", conn, if_exists="replace", schema=schema )
3. 验证结果
执行以下SQL确认表结构和数据:
-- 查看列类型 SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'test_arrays'; -- 查询数据 SELECT * FROM test_arrays;
此时foo列类型应为real[],数据会以PostgreSQL原生数组格式存储,而非文本字符串。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

