当前位置: 首页 > 知识库问答 >
问题:

duckdb 的 python sdk 读取 csv 的时候,如何指定列的字段类型?

魏翰
2024-09-26
─➤  pip show duckdb                     
Name: duckdb
Version: 1.1.1
Summary: DuckDB in-process database
Home-page: https://www.duckdb.org
Author: 
Author-email: 
License: MIT
Location: /home/pon/.local/share/virtualenvs/taisan_console-0970Xq3e/lib/python3.11/site-packages
Requires: 
Required-by: 

使用下面的代码读取一个 csv 文件,但是会报错

excel_file_path = 'dev/周度产出(9.16-9.22).csv'
query = f"""
SELECT * 
FROM '{excel_file_path}'
"""
df = duckdb.query(query).df()

看起来是因为类型的问题

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/pon/code/work/vobile/vobile-it/taisan_console/dev/found_ma_from_csv_batch.py", line 21, in <module>
    df = duckdb.query(query).df()
         ^^^^^^^^^^^^^^^^^^^^^^^^
duckdb.duckdb.ConversionException: Conversion Error: CSV Error on Line: 25716
Original Line: 
2024/9/16-2024/9/22,BM-BQBH-2023-3,央视国际2023年新媒体视频版权监测服务协议,新浪新闻,https://k.sina.cn/article_2110705772_m7dced06c033016q3c.html,萧敬腾郁可唯把李清照的词唱成歌,微博电视,-,-,-,已下线,2024-09-19,系统,中央广播电视总台2024中秋晚会,系统,-
Error when converting column "监测日期". Could not convert string "-" to 'DATE'

Column 监测日期 is being converted as type DATE
This type was auto-detected from the CSV file.
Possible solutions:
* Override the type for this column manually by setting the type explicitly, e.g. types={'监测日期': 'VARCHAR'}
* Set the sample size to a larger value to enable the auto-detection to scan more values, e.g. sample_size=-1
* Use a COPY statement to automatically derive types from an existing table.

  file=dev/周度产出(9.16-9.22).csv
  delimiter = , (Auto-Detected)
  quote = " (Auto-Detected)
  escape = " (Auto-Detected)
  new_line = \r\n (Auto-Detected)
  header = true (Auto-Detected)
  skip_rows = 0 (Auto-Detected)
  comment = \0 (Auto-Detected)
  date_format =  (Auto-Detected)
  timestamp_format =  (Auto-Detected)
  null_padding=0
  sample_size=20480
  ignore_errors=false
  all_varchar=0

所以如何在读取 csv 的时候指定类型?


问了一个 ai,答案都是不行的

chatgpt ❌

query = f"SELECT * FROM '{excel_file_path}' WITH (types={{'监测日期': 'VARCHAR'}})"
df = duckdb.query(query).df()

智谱清言 ❌

query = f"""
SELECT * 
FROM '{excel_file_path}' 
(监测日期 VARCHAR)
"""
df = duckdb.query(query).df()

豆包 ❌

import duckdb

# 指定列的类型映射
types = {'column_name': 'data_type'}

# 读取 CSV 文件并指定列类型
query = f"SELECT * FROM '{csv_file_path}' (types={types})"
df = duckdb.query(query).df()

共有2个答案

许茂才
2024-09-26

问一堆AI为什么就是不敢看一眼官方文档? https://duckdb.org/docs/data/csv/overview.html

你的绝大多数问题都可以阅读官方文档解决!

鲁鹏
2024-09-26

在 DuckDB 中,当你从 CSV 文件读取数据时,并希望指定列的数据类型,你需要使用 READ_CSV 函数或者通过 COPY 语句,并在这些语句中明确指定列的类型。直接使用 SELECT * FROM 'filename' 是不支持直接在查询中指定列类型的。

以下是一个使用 READ_CSV 函数的例子,该函数允许你指定列的类型:

import duckdb

# 连接到 DuckDB
conn = duckdb.connect()

# CSV 文件路径
excel_file_path = 'dev/周度产出(9.16-9.22).csv'

# 指定列的类型
types = "监测日期 VARCHAR, 其他列名1 数据类型1, 其他列名2 数据类型2, ..."
# 注意:你需要替换 '其他列名1 数据类型1, 其他列名2 数据类型2, ...' 为你的 CSV 文件中实际的列名和对应的数据类型

# 使用 READ_CSV 函数读取 CSV 并指定类型
query = f"""
CREATE VIEW my_csv_view AS
SELECT *
FROM read_csv('{excel_file_path}', header=true, types='{types}');
"""

# 执行查询
conn.execute(query)

# 从视图中选择数据
df = conn.execute("SELECT * FROM my_csv_view").df()

# 关闭连接
conn.close()

# 现在 df 包含了你从 CSV 文件中读取的数据,并且列的类型已经按照你的指定进行了转换

注意:

  1. 你需要将 types 字符串中的 '监测日期 VARCHAR, 其他列名1 数据类型1, 其他列名2 数据类型2, ...' 替换为你的 CSV 文件中实际的列名和对应的数据类型。
  2. read_csv 函数的 header=true 参数假设你的 CSV 文件第一行是列名。如果不是,请将其设置为 false
  3. 使用 CREATE VIEW 是为了将读取的数据存储为一个视图,这样你就可以像查询普通表一样查询它。当然,你也可以直接将 read_csv 的结果赋值给一个 DataFrame,但这通常涉及到更复杂的 SQL 语句或 DuckDB 的 Python API 的其他用法。

确保你的 DuckDB 版本支持 read_csv 函数,因为这是一个相对较新的功能。如果你使用的是较旧的版本,可能需要更新 DuckDB 或使用其他方法来读取 CSV 并指定列类型。

 类似资料:
  • 我想读Spark的CSV。所以我使用Java中的命令。 谢谢大家。

  • 我有一个csv文件,如下所示: ... 我怎样才能在python中只读取列“AAA、DDD、FFF、GGG”并跳过标题?我想要的输出是一个元组列表,如下所示:[(1,4,3,20),(2,5,2,23),(4,6,1,22)]。我正在考虑稍后将这些数据写入SQLdatabase。 我参考了这篇文章:用csv模块从csv文件中读取特定的列?。但是我不认为这对我有什么帮助。因为我的. csv很大,有一

  • 问题内容: 我有一个csv文件,看起来像这样: … 如何只读取python中的“ AAA,DDD,FFF,GGG”列并跳过标题?我想要的输出是一个看起来像这样的元组列表:[(1,4,3,20),(2,5,2,23),(4,6,1,22)]。我正在考虑稍后将这些数据写入SQLdatabase。 我提到了这篇文章:使用csv模块从csv文件中读取特定的列?。但是我认为这对我的情况没有帮助。由于我的.c

  • 我有一个包含5个字段(列)的csv文件。在5列中,我只想读第二列和第四列,这是进一步处理所需的。现在我正在使用opencsv api的readAll()方法进行读取。通过使用这种方法,我必须处理所有列,以获得第二列和第四列的值。 有没有办法读取所需列的值,即从csv文件中读取第二个和第四个值? 这是正确的方法还是我应该使用其他方法?

  • 我有一个csv文件,其中包含4个字段(列)。在4列中,我想读第二列,想读csv文件的特定列的第一个名称,并使用Java计算列记录。请帮忙。

  • 问题内容: 我在第3方中设计的课程很差,我需要访问它的一个私有字段。例如,为什么我需要选择私有字段? 如何使用反射获取值? 问题答案: 为了访问私有字段,你需要从类的声明字段中获取它们,然后使其可访问: 编辑:正如所说,访问字段,将字段设置为可访问并检索值都可能引发,尽管上面需要注释的唯一检查异常。 在NoSuchFieldException如果你问一个字段由不符合声明的字段的名称将被抛出。 该会