在Linux上使用DuckCP实现从csv文件汇总数据到SQLite数据库的表

从pypi网站Duckcp页面下载duckcp-0.1.1-py3-none-any.whl
一开始用的Python 3.11.2环境。
继续沿用上文打补丁的方法,得到一个支持python3.11.1的安装包。
因为缺少zip压缩工具,使用python程序来完成对修改后文件的重新压缩。

import os
import zipfile
from pathlib import Pathdef zip_directory_contents(source_dir, output_zip):"""压缩目录下的所有内容到ZIP文件(不包括根目录本身):param source_dir: 要压缩的目录路径:param output_zip: 输出的ZIP文件路径"""source_path = Path(source_dir).resolve()with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:for root, dirs, files in os.walk(source_dir):# 计算相对于源目录的路径rel_path = os.path.relpath(root, start=source_path)for file in files:file_path = Path(root) / file# 在ZIP中存储的相对路径(去掉最外层的a/)arcname = os.path.join(rel_path, file)zipf.write(file_path, arcname=arcname)# 确保空目录也被包含if not files and not dirs:# 添加空目录(必须以/结尾)rel_dir = os.path.relpath(root, start=source_path) + '/'zipf.writestr(rel_dir, '')zip_directory_contents('/par/whl/', '/par/whloutput_zip')

将得到的zip文件重命名为原始文件名,然后安装

mv /par/whloutput_zip /par/duckcp-0.1.1-py3-none-any.whlpython3 pip.pyz install  /par/duckcp-0.1.1-py3-none-any.whl --break-system-packages -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

安装过程没有报错。
1.创建配置元数据库

duckcp meta create
Traceback (most recent call last):File "/usr/local/bin/duckcp", line 5, in <module>from duckcp import mainFile "/usr/local/lib/python3.11/dist-packages/duckcp/__init__.py", line 5, in <module>from duckcp.boot import app, meta_command, repository_command, storage_command, transformer_command, task_commandFile "/usr/local/lib/python3.11/dist-packages/duckcp/boot/__init__.py", line 5, in <module>from duckcp.configuration.meta_configuration import enable_metadata_configurationFile "/usr/local/lib/python3.11/dist-packages/duckcp/configuration/meta_configuration.py", line 9, in <module>from duckcp.entity.executor import ExecutorFile "/usr/local/lib/python3.11/dist-packages/duckcp/entity/executor.py", line 69def records[T: tuple[Any, ...]](self, sql: str, *parameters: Any, constructor: RecordConstructorProtocol[T] = None) -> list[T]:^
SyntaxError: expected '('

创建元数据库报错,应该就是不支持python3.11版本。改用Python 3.13.1,这一步顺利完成。需要说明,这些步骤都是由于我的环境和软件要求的Python版本不同引起的,如果版本正确, 这些问题都不会发生。

duckcp meta create2025-07-28 07:02:08.448 INFO duckcp.service.meta_service#meta_create : 配置文件(/root/.config/com.yinfn.duckcp/configuration.db)初始化                                      ]8;id=117526;file:///usr/local/lib/python3.13/site-packages/duckcp/service/meta_service.pymeta_service.py]8;;:]8;id=511219;file:///usr/local/lib/python3.13/site-packages/duckcp/service/meta_service.py#2020]8;;
2025-07-28 07:02:08.452 INFO duckcp.service.meta_service#meta_create : 执行脚本(001-repositories.sql)                                                                       ]8;id=289077;file:///usr/local/lib/python3.13/site-packages/duckcp/service/meta_service.pymeta_service.py]8;;:]8;id=303663;file:///usr/local/lib/python3.13/site-packages/duckcp/service/meta_service.py#2424]8;;

命令输出的信息有点多,向软件作者张泽鹏先生请教,他说可以用-q选项减少输出。但我们首次使用时,信息多更有利于排查问题。
2.创建源和目标存储库
因为我要实现从csv文件汇总数据,所以要在配置元数据库中登记csv文件存储位置。
通过以下命令完成

duckcp repository create 文件仓库 -k file --folder data

作为数据源的csv文件,直接复制自duckcp例子,因为复制出来的字符分隔符是tab字符,所以改名为progs.tsv

id	name	language
1	Joe	Java
2	Alice	JavaScript
3	Leon	C/C++
4	William	Java
5	James	C/C++
6	Enson	C/C++

对于目标,我一开始用的命令是,

duckcp repository create sqlite -k sqlite  --folder data --file sqlite.db

以为这样就能把data目录下的sqlite.db数据库作为目标,其实不然,打开配置元数据库检查,里面的内容如下。

./sqlite3 $HOME/.config/com.yinfn.duckcp/configuration.db
sqlite> .tables
credentials         snapshots           tasks               transformers      
repositories        storages            tasks_transformerssqlite> .header on
sqlite> select * from repositories;
id|kind|code|properties|created_at|updated_at
1|file|文件仓库|{"folder":"/par/data"}|2025-07-28 07:18:32|2025-07-28 07:18:32
2|sqlite|sqlite|{"file":"/par/sqlite.db","folder":"/par/data"}|2025-07-28 07:20:25|2025-07-28 07:20:25

sqlite所在行的properties列显示不符合预期。
张泽鹏先生说,数据库无需使用–folder参数,只要在–file中写明完整路径即可。所以正确命令如下:

duckcp repository create sqlite2 -k sqlite --file data/sqlite.db

因为duckcp本质上是一个ETL工具,它不会帮我们建库,所以要事先手工用sqlite软件实际创建data目录下的sqlite.db数据库,并建立保存目标数据的表。

./sqlite3 data/sqlite.db
sqlite> create table prog_sum(language varchar,cnt int);
sqlite> .exit

3.创建存储单元
存储单元这个名字的含义是数据库里的表的别名,我一开始漏掉了这一步,执行后面的命令就出错了main : 目标仓库(sqlite2)的存储单元(prog_sum)不存在

duckcp storage create prog_sum -r sqlite2 --table prog_sum

4.创建数据迁移任务
第一步是建立一个sql脚本,它负责读取源表(本例是Csv文件)执行汇总。
我直接照搬duckcp例子中的脚本,改了文件名。保存为data/trans.sql

select"language" as "编程语言",count(*) as "程序员人数"
fromread_csv('progs.tsv')
group by"language"
order by"程序员人数" desc

然后执行命令

duckcp transformer create 数据统计 -s 文件仓库 -t sqlite2 -o prog_sum -f data/trans.sql

5.执行数据迁移任务

duckcp transformer execute 数据统计
2025-07-28 08:28:36.086 INFO duckcp.transform.database_transform#database_transform : 清空表(DELETE FROM "prog_sum")                                                  ]8;id=758441;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.pydatabase_transform.py]8;;:]8;id=170976;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.py#3030]8;;
2025-07-28 08:28:36.221 INFO duckcp.transform.database_transform#database_transform : 批量添加数据(INSERT INTO "prog_sum" ("编程语言", "程序员人数") VALUES (?, ?))   ]8;id=941332;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.pydatabase_transform.py]8;;:]8;id=508716;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.py#3535]8;;
2025-07-28 08:28:36.224 ERROR duckcp#main : table prog_sum has no column named 编程语言  

又报错了,但这是最后一个错误,提示信息也很明确,只要把目标表的列名改成和上述sql一模一样的列名就行了。

./sqlite3 data/sqlite.db
sqlite> alter table prog_sum rename language to "编程语言";
sqlite> alter table prog_sum rename cnt to "程序员人数";
sqlite> .exit

再次执行任务,当看到transformer_execute : 从仓库(文件仓库)迁移数据到仓库(sqlite2)的存储单元(prog_sum) 信息就表明数据迁移成功,此时可以用sqlite打开目标表,结果符合预期。

sqlite> select * from prog_sum;
C/C++|3
Java|2
JavaScript|1

下面验证源文件更新后,数据重新汇总的结果被转移到目标表。

./duckdb131
DuckDB v1.3.1 (Ossivalis) 2063dda3e6
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.D select * from 'data/progs.tsv';
┌───────┬─────────┬────────────┐
│  id   │  name   │  language  │
│ int64 │ varcharvarchar   │
├───────┼─────────┼────────────┤
│     1 │ Joe     │ Java       │
│     2 │ Alice   │ JavaScript │
│     3 │ Leon    │ C/C++      │
│     4 │ William │ Java       │
│     5 │ James   │ C/C++      │
│     6 │ Enson   │ C/C++      │
└───────┴─────────┴────────────┘
D copy( from 'data/progs.tsv' union all select 7,'zhang3','sql') to 'data/progs.tsv'; 
D select * from 'data/progs.tsv';
┌───────┬─────────┬────────────┐
│  id   │  name   │  language  │
│ int64 │ varcharvarchar   │
├───────┼─────────┼────────────┤
│     1 │ Joe     │ Java       │
│     2 │ Alice   │ JavaScript │
│     3 │ Leon    │ C/C++      │
│     4 │ William │ Java       │
│     5 │ James   │ C/C++      │
│     6 │ Enson   │ C/C++      │
│     7 │ zhang3  │ sql        │
└───────┴─────────┴────────────┘
D .exit
root@217449ea9d61:/par# duckcp transformer execute 数据统计
2025-07-28 08:51:51.005 INFO duckcp.transform.database_transform#database_transform : 清空表(DELETE FROM "prog_sum")                                                  ]8;id=353910;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.pydatabase_transform.py]8;;:]8;id=259843;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.py#3030]8;;
2025-07-28 08:51:51.123 INFO duckcp.transform.database_transform#database_transform : 批量添加数据(INSERT INTO "prog_sum" ("编程语言", "程序员人数") VALUES (?, ?))   ]8;id=595510;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.pydatabase_transform.py]8;;:]8;id=232644;file:///usr/local/lib/python3.13/site-packages/duckcp/transform/database_transform.py#3535]8;;
2025-07-28 08:51:51.323 INFO duckcp.service.transformer_service#transformer_execute : 从仓库(文件仓库)迁移数据到仓库(sqlite2)的存储单元(prog_sum)                   ]8;id=489086;file:///usr/local/lib/python3.13/site-packages/duckcp/service/transformer_service.pytransformer_service.py]8;;:]8;id=370598;file:///usr/local/lib/python3.13/site-packages/duckcp/service/transformer_service.py#273273]8;;
root@217449ea9d61:/par# ./sqlite3 data/sqlite.db
SQLite version 3.42.0 2023-05-16 12:36:15
Enter ".help" for usage hints.
sqlite> .header on
sqlite> select * from prog_sum;
编程语言|程序员人数
C/C++|3
Java|2
sql|1
JavaScript|1

可见,结果多出了sql|1这行,它就是数据源插入zhang3的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90873.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于深度学习的图像分类:使用EfficientNet实现高效分类

前言 图像分类是计算机视觉领域中的一个基础任务&#xff0c;其目标是将输入的图像分配到预定义的类别中。近年来&#xff0c;深度学习技术&#xff0c;尤其是卷积神经网络&#xff08;CNN&#xff09;&#xff0c;在图像分类任务中取得了显著的进展。EfficientNet是一种新型的…

Java基础-综合案例

1、设计一个可以执行基本数学运算&#xff08;加减乘除&#xff09;的计算器程序功能描述&#xff1a;用户输入两个数字、一个运算符&#xff08;、-、*、/&#xff09;。根据所选运算符执行相应的数学运算&#xff0c;显示运算结果。import java.util.Scanner;public class Te…

四、计算机组成原理——第3章:存储系统

目录 3.1存储器概述 3.1.1存储器的分类 1.按在计算机中的作用(层次)分类 2.按存储介质分类 3.按存取方式分类 4.按信息的可保存性分类 3.1.2存储器的性能指标 3.2主存储器 3.2.1SRAM芯片和DRAM芯片 1.SRAM的工作原理 2.DRAM的工作原理 3.SRAM和DRAM的比较 4.存储器芯片的内部结…

3D Semantic Occupancy Prediction

3D 语义占用预测&#xff08;3D Semantic Occupancy Prediction&#xff09;旨在将真实世界环境划分为规则的三维体素&#xff08;voxel&#xff09;网格&#xff0c;并对每个体素同时预测&#xff1a; 占用状态&#xff08;Occupancy&#xff09;&#xff1a;该体素是否被物体…

在Word和WPS文字中添加的拼音放到文字右边

在Word和WPS文字中&#xff0c;可以方便地为中文汉字添加拼音。默认的是拼音在汉字的上方&#xff0c;而且不方便直接编辑。可以简单操作后把拼音放在汉字的右边&#xff0c;并且可以方便地编辑。一、Word&#xff1a;先为汉字添加拼音&#xff0c;然后选择性粘贴为纯文本即可1…

Torchv Unstrustured 文档解析库

一个强大且开发者友好的文档解析库&#xff0c;专为RAG&#xff08;检索增强生成&#xff09;应用优化。基于Apache Tika、Apache POI和PDFBox等业界标准Java库构建&#xff0c;TorchV Unstructured提供了增强的解析能力&#xff0c;具备智能表格结构识别和内容提取功能。 &am…

30天入门Python(基础篇)——第22天:面向对象之继承与多继承

目录 专栏导读 学习目标 1. 继承的基本概念 1.1 继承的优势 2. 单继承 2.1 基本语法 2.2 实际示例 3. super()函数详解 3.1 基本用法 3.2 super()的高级用法 4. 多继承 4.1 多继承语法 4.2 多继承示例 5. 方法解析顺序(MRO) 5.1 查看MRO 5.2 复杂的MRO示例 6. 实际应用案例 6…

学习人工智能所需知识体系及路径详解

一、核心基础知识体系1. 数学基础线性代数关键概念&#xff1a;向量空间、矩阵运算&#xff08;转置/逆矩阵&#xff09;、特征值分解、奇异值分解&#xff08;SVD&#xff09;应用场景&#xff1a;数据降维&#xff08;PCA&#xff09;、图像处理&#xff08;矩阵变换&#xf…

前端实现银河粒子流动特效的技术原理与实践

文章目录 1,引言 2,特效效果简介 3,技术原理解析 1. 粒子系统基础 2. 银河结构的数学建模 3. 动态流动与旋转 4,实现流程图 5,关键代码实现与详细讲解 1. 初始化Three.js场景 2. 生成银河粒子数据 3. 创建粒子几何体与材质 4. 实现粒子的动态旋转与动画 5. 可选:粒子颜色…

Qt_Gif_Creator 基于Qt的屏幕gif录制工具

本文介绍了一个基于Qt框架的屏幕GIF录制工具的实现。该工具包含XYGifCreator类负责GIF创建逻辑&#xff0c;使用Gif.h库进行GIF编码&#xff1b;XYGifFrame类提供GUI界面&#xff0c;支持设置录制区域大小、帧率以及保存位置。工具采用多线程处理GIF编码&#xff0c;支持Window…

Linux实战:HAProxy全方位指南

一、负载均衡核心概念 1.1 负载均衡定义 负载均衡&#xff08;Load Balance&#xff0c;简称LB&#xff09;是一种基于硬件设备或软件服务的高可用反向代理技术。它将特定业务&#xff08;如Web服务、网络流量&#xff09;分发到后端的一个或多个服务器/设备&#xff0c;从而提…

22 BTLO 蓝队靶场 Countdown 解题记录

Tools: - ELK - CyberChef - OSINT (whole World Wide Web) Hunt #1: Brute Force DetectedSource: winevent-security (1/3) — 可疑暴力破解流量来自哪个IP地址 What is the IP address from which the suspicious brute force traffic is seen?? 我们需要寻找暴力破解…

文心一言4.5开源模型实战:ERNIE-4.5-0.3B轻量化部署与效能突破

文心一言4.5开源模型实战&#xff1a;ERNIE-4.5-0.3B轻量化部署与效能突破 文心一言4.5开源模型实战&#xff1a;ERNIE-4.5-0.3B轻量化部署与效能突破&#xff0c;本文介绍百度文心一言 4.5 开源模型中 ERNIE-4.5-0.3B 的轻量化部署与效能。该 3 亿参数模型破解大模型落地的算力…

SAP-MM-采购订单批量创建 excel 版

采购订单批量创建程序摘要:不含任何定制字段的导入,直接导入系统即可使用 该SAP ABAP程序实现采购订单的批量创建功能,主要特性包括: 支持通过Excel文件批量导入采购订单数据(XLS/XLSX格式) 提供数据校验功能,包括: 物料号有效性检查 采购凭证存在性验证 科目分配类别…

2_软件重构_一种组件化开发方式

一、碎碎念 首先先考虑下&#xff0c;什么情况下软件需要重构&#xff1f;我觉得答案有很多种&#xff0c;而且还有范围。当日益增长的需求与现有软件结构越来越无法匹配时——①具体表现可能为新增需求所导致的bug越来越多&#xff0c;一个新功能的改动牵一发而动全身&a…

今日行情明日机会——20250728

上证指数量能持续在200天均量线上&#xff0c;最近今天横盘震荡&#xff0c;今天依然收在5天均线上方&#xff0c;个股涨跌个数基本相同。目前依然强势&#xff0c;有望冲击3674的前高。需要注意板块的高低切换。深证指数今天缩量收小阳线&#xff0c;均线多头的趋势明显&#…

【iOS】类和分类的加载过程

目录 前言 _objc_init方法 environ_init tis->init方法 static_init方法 &#x1f4a1; _objc_init 是由 libc 调用的&#xff0c;目的是&#xff1a; ❗️“必须自己实现” 是什么意思&#xff1f; runtime_init exception_init cache_t::init _imp_implementati…

大模型算法面试笔记——常用优化器SGD,Momentum,Adagrad,RMSProp,Adam

常用参数&#xff1a;ttt-步数&#xff0c;α\alphaα-学习率&#xff0c;θ\thetaθ-参数&#xff0c;f(θ)f(\theta)f(θ)-目标函数&#xff0c;gtg_tgt​-梯度&#xff0c;β1\beta_1β1​-一阶矩衰减系数&#xff0c;通常取0.9&#xff0c;β2\beta_2β2​-二阶矩&#xff…

【计算机毕业设计】基于SSM的小型超市管理系统+LW

博主介绍&#xff1a;✌全网粉丝3W,csdn特邀作者、CSDN新星计划导师、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、…

火线、零线、地线

我们可以用 “水流” 来比喻 “电流”&#xff0c;这样理解起来会很简单&#xff1a;想象一下你家的电路就像一个 “闭合的水循环系统”&#xff1a;&#x1f525; 1. 火线 (Live Wire) - 好比 “进水管的高压端”作用&#xff1a; 从发电厂或变压器输送 高压电 到你家的插座或…