DuckDB:Golang操作DuckDB实战案例

DuckDB是一个嵌入式SQL数据库引擎。它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的。DuckDB支持各种数据类型和SQL特性。凭借其在以内存为中心的环境中处理高速分析的能力,它迅速受到数据科学家和分析师的欢迎。在这篇博文中,我们将探索在Go中使用DuckDB。

在这里插入图片描述

DuckDB的主要优点

  • 内存内执行:DuckDB主要在内存中操作,但也支持内存外执行。这使得它能够非常快速有效地执行计算。
  • 完整的SQL支持:DuckDB支持广泛的SQL特性,这使得它对于各种类型的数据操作非常灵活。
  • 事务支持:DuckDB支持事务,这是在许多应用程序中维护数据完整性和一致性的关键特性。
  • 向量化执行:DuckDB使用向量化查询执行,从而提高CPU利用率和性能。
  • 易于集成:DuckDB为多种编程语言提供api,包括Python、R、c++、Rust、Java和Go。这使得将DuckDB集成到现有工作流和系统中变得更加容易。
  • 开源:DuckDB是开源的,这意味着它的源代码可以免费修改或增强。这允许社区驱动的改进和对特定用例的适应性。
    在这里插入图片描述

环境准备

在开始使用DuckDB和Go之前,需要安装DuckDB Go驱动程序。你可以使用Go的包管理器下载。在终端上运行以下命令:

github.com/marcboeker/go-duckdb
  • 连接数据库
package mainimport ("database/sql""log"_ "github.com/marcboeker/go-duckdb"
)func main() {// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename heredb, err := sql.Open("duckdb", "")if err != nil {log.Fatal("Failed to connect to database:", err)}defer db.Close()
}

安装了驱动程序后,现在可以从Go应用程序建立到DuckDB的连接。sql.Open() 函数用于连接到DuckDB,空数据源名称表示我们正在使用内存中的数据库,你也可以指定数据库文件名称,实现数据持久化,相对于当前项目所在目录。

初始化表和数据

现在连接已经建立,你可以执行各种数据库操作了。我们首先创建表,然后插入初始化数据进行测试:

package mainimport ("database/sql""fmt""log""time"_ "github.com/marcboeker/go-duckdb"
)var db *sql.DB
var err errorfunc main() {// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename heredb, err = sql.Open("duckdb", "data.db")if err != nil {log.Fatal("Failed to connect to database:", err)}defer db.Close()init_data()
}func init_data() {// Create table_, err := db.Exec(`CREATE TABLE employee (id INTEGER,name VARCHAR(20),start_dt TIMESTAMP,is_remote BOOLEAN)`)if err != nil {log.Fatal(err)}// Insert some data in table_, err = db.Exec(`INSERT INTO employee (id, name, start_dt, is_remote)VALUES(1, 'John Doe', '2022-01-01 09:00:00', true),(2, 'Jane Smith', '2023-03-15 10:00:00', false)`)if err != nil {log.Fatal(err)}
}

在处理较大的数据集时,考虑使用事务和预处理语句以提高效率和安全性。记住,总是处理错误并在完成后关闭连接。

查询单行或多行

要获取数据,可以使用QueryRow() 函数来选择单行:

func query_one() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query single rowif err := db.QueryRow("SELECT id, name, start_dt, is_remote FROM employee WHERE id = ?", 1).Scan(&id, &name, &startDt, &isRemote); err != nil {if err == sql.ErrNoRows {log.Println("No rows found.")} else {log.Fatalf("unable to execute query: %v", err)}} else {fmt.Println("Select 1 row result:\nID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)}
}

不要忘记处理任何错误并正确关闭连接和结果集,如上所示。

要选择多行,可以使用Query() 函数:

func query_all() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query multiple rowsrows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")if err != nil {log.Fatal(err)}defer rows.Close()// Print the resultsfmt.Println("Results:")for rows.Next() {err = rows.Scan(&id, &name, &startDt, &isRemote)if err != nil {log.Fatal(err)}fmt.Println("ID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)}err = rows.Err()if err != nil {log.Fatal(err)}
}

我们用SQL命令调用Query()函数,从employee表中选择所有记录。

  • 然后使用rows.Next()进入循环,该循环遍历查询返回的每一行。
  • 在循环中,我们使用Scan()函数将当前行的列复制到id、name、startDt和isRemote变量中。
  • 然后使用fmt.Println()函数打印这些变量。
  • 循环结束后,使用rows.Err()检查迭代过程中的错误。如果有错误,我们使用log.Fatal(err)打印它。

错误处理和事务

在现实世界中,Go代码必须准备好处理错误和处理事务。SQL包提供了所有必要的工具:

func trans_insert() {// Error handling and transactionstx, err := db.Begin()if err != nil {log.Fatal(err)}defer tx.Rollback()_, err = tx.Exec(`INSERT INTO employee (id, name, start_dt, is_remote)VALUES(3000000000, 'id int64 instead of int32', '2022-06-17 11:00:00', true)`)if err != nil {log.Printf("ERROR: %s\n", err.Error()) // Do not fail, just print the error in output}err = tx.Commit()if err != nil {log.Fatal(err)}
}

此代码开始事务,尝试执行插入语句,然后提交事务。如果在执行期间发生错误,它将回滚在该事务中所做的任何更改。

完整代码

package mainimport ("database/sql""fmt""log""time"_ "github.com/marcboeker/go-duckdb"
)var db *sql.DB
var err errorfunc main() {// Empty datasource means, that DB will be solely in-memory, otherwise you could specify a filename heredb, err = sql.Open("duckdb", "data.db")if err != nil {log.Fatal("Failed to connect to database:", err)}defer db.Close()// init_data()query_one()// trans_insert()query_all()
}func init_data() {// Create table_, err = db.Exec(`CREATE TABLE employee (id INTEGER,name VARCHAR(20),start_dt TIMESTAMP,is_remote BOOLEAN)`)if err != nil {log.Fatal(err)}// Insert some data in table_, err = db.Exec(`INSERT INTO employee (id, name, start_dt, is_remote)VALUES(1, 'John Doe', '2022-01-01 09:00:00', true),(2, 'Jane Smith', '2023-03-15 10:00:00', false)`)if err != nil {log.Fatal(err)}
}func trans_insert() {// Error handling and transactionstx, err := db.Begin()if err != nil {log.Fatal(err)}defer tx.Rollback()_, err = tx.Exec(`INSERT INTO employee (id, name, start_dt, is_remote)VALUES(3000000000, 'id int64 instead of int32', '2022-06-17 11:00:00', true)`)if err != nil {log.Printf("ERROR: %s\n", err.Error()) // Do not fail, just print the error in output}err = tx.Commit()if err != nil {log.Fatal(err)}
}func query_one() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query single rowif err := db.QueryRow("SELECT id, name, start_dt, is_remote FROM employee WHERE id = ?", 1).Scan(&id, &name, &startDt, &isRemote); err != nil {if err == sql.ErrNoRows {log.Println("No rows found.")} else {log.Fatalf("unable to execute query: %v", err)}} else {fmt.Println("Select 1 row result:\nID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)}
}func query_all() {// Variables to store query resultvar id intvar name stringvar startDt time.Timevar isRemote bool// Query multiple rowsrows, err := db.Query("SELECT id, name, start_dt, is_remote FROM employee")if err != nil {log.Fatal(err)}defer rows.Close()// Print the resultsfmt.Println("Results:")for rows.Next() {err = rows.Scan(&id, &name, &startDt, &isRemote)if err != nil {log.Fatal(err)}fmt.Println("ID:", id, "Name:", name, "Start Datetime:", startDt, "Is Remote:", isRemote)}err = rows.Err()if err != nil {log.Fatal(err)}
}

最后总结

DuckDB对Go的支持允许开发人员直接从他们的Go应用程序中执行强大的数据分析操作。强大的数据管理系统和通用高效的编程语言之间的这种集成为更先进的数据处理应用打开了大门。有了本文提供的基础知识,你就可以开始探索这些可能性了。

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

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

相关文章

day1代码练习

输出3-100以内的完美数&#xff0c;(完美数&#xff1a;因子和(因子不包含自身)数本身) #include <stdio.h>// 判断一个数是否为完美数的函数 int panduan(int n) {if (n < 2) {return 0; // 小于2的数不可能是完美数}int sum 1; // 因子和初始化为1&#xff08;因…

dify大模型应用开发平台搭建

原文地址&#xff1a;dify大模型应用开发平台搭建 – 无敌牛 欢迎参观我的技术分享网站&#xff1a;无敌牛 – 技术/著作/典籍/分享等 之前分享了一个私有化部署开源大模型的方法&#xff0c;具体参看往期文章&#xff1a;私有化部署开源AI模型 – 无敌牛 今天搭建一个大模型…

PC端实现PDF预览(支持后端返回文件流 || 返回文件URL)

一、使用插件 插件名称&#xff1a;vue-office/pdf 版本&#xff1a;2.0.2 安装插件&#xff1a;npm i vue-office/pdf^2.0.2 1、“vue-office/pdf”: “^2.0.2”, 2、 npm i vue-office/pdf^2.0.2 二、代码实现 // 引入组件 &#xff08;在需要使用的页面中直接引入&#x…

【统计信号处理基础——估计与检测理论】Vol1.Ch1. 引言

系列目录 【统计信号处理基础——估计与检测理论】Vol1.Ch2. 最小方差无偏估计 文章目录 1. 信号处理中的估计2. 估计的数学问题3. 估计量性能评估习题1.11.21.31.41.5 1. 信号处理中的估计 从离散时间波形或一组数据集中提取参数的问题。我们有 N N N点数据集 { x [ 0 ] , x …

Spring Boot 邂逅Netty:构建高性能网络应用的奇妙之旅

一、引言 在当今数字化时代&#xff0c;构建高效、可靠的网络应用是开发者面临的重要挑战。Spring Boot 作为一款强大的 Java 开发框架&#xff0c;以其快速开发、简洁配置和丰富的生态支持&#xff0c;深受广大开发者喜爱。而 Netty 作为高性能、异步的网络通信框架&#xff…

【openwrt】openwrt odhcpd IPv6 prefix_filter选项说明

prefix_filter 在 OpenWrt 的 odhcpd 配置中,prefix_filter 是一个重要的选项,用于控制哪些 IPv6 前缀可以通过 Router Advertisement (RA) 或 DHCPv6 广播到客户端 prefix_filter 的作用 prefix_filter 的主要功能是限制路由器向客户端广播的 IPv6 前缀。它允许管理员指定一…

Spring--SpringMVC使用(接收和响应数据、RESTFul风格设计、其他扩展)

SpringMVC使用 二.SpringMVC接收数据2.1访问路径设置2.2接收参数1.param和json2.param接收数据3 路径 参数接收4.json参数接收 2.3接收cookie数据2.4接收请求头数据2.5原生api获取2.6共享域对象 三.SringMVC响应数据3.1返回json数据ResponseBodyRestController 3.2返回静态资源…

Unity在WebGL中拍照和录视频

原工程地址https://github.com/eangulee/UnityWebGLRecoder Unity版本2018.3.6f1&#xff0c;有点年久失修了 https://github.com/xue-fei/Unity.WebGLRecorder 修改jslib适配了Unity2021 效果图 录制的视频 Unity在WebGL中拍照和录视频

数据结构——AVL树的实现

Hello&#xff0c;大家好&#xff0c;这一篇博客我们来讲解一下数据结构中的AVL树这一部分的内容&#xff0c;AVL树属于是数据结构的一部分&#xff0c;顾名思义&#xff0c;AVL树是一棵特殊的搜索二叉树&#xff0c;我们接下来要讲的这篇博客是建立在了解搜索二叉树这个知识点…

无监督<视觉-语言>模型中的跨模态对齐

在当前的人工智能领域&#xff0c;跨模态学习尤其是视觉和语言的结合&#xff0c;正迅速成为一项基础性技术。传统的视觉模型和语言模型大多是分开训练的&#xff0c;处理独立模态的数据。然而&#xff0c;随着视觉-语言模型&#xff08;Vision-Language Models, VLMs&#xff…

后端SpringBoot学习项目-用户管理-增删改查-service层

仓库地址 在初版代码中&#xff0c;已经实现了基础的增删改查。 但是&#xff0c;逻辑处理都放在Controller层中并没有分为Service层&#xff0c;所以&#xff0c;代码升级时候必须补充上去。 代码结构 升级后的代码结构有所变化。 --common 公共插件 --controller…

【25美赛A题-F题全题目解析】2025年美国大学生数学建模竞赛(MCM/ICM)解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

jenkins-k8s pod方式动态生成slave节点

一. 简述&#xff1a; 使用 Jenkins 和 Kubernetes (k8s) 动态生成 Slave 节点是一种高效且灵活的方式来管理 CI/CD 流水线。通过这种方式&#xff0c;Jenkins 可以根据需要在 Kubernetes 集群中创建和销毁 Pod 来执行任务&#xff0c;从而充分利用集群资源并实现更好的隔离性…

详解:TCP/IP五层(四层)协议模型

一.五层&#xff08;四层&#xff09;模型 1.概念 TCP/IP协议模型分为五层&#xff1a;物理层、数据链路层、网络层、传输层和应用层。这五层每一层都依赖于其下一层给它提供的网络去实现需求。 1&#xff09;物理层&#xff1a;这是最基本的一层&#xff0c;也是最接近硬件…

关于java实现word(docx、doc)转html的解决方案

最近在研究一些关于文档转换格式的方法&#xff0c;因为需要用在开发的一个项目上&#xff0c;所以投入了一些时间&#xff0c;给大家聊下这块逻辑及解决方案。 一、关于word转换html大致都有哪些方法&#xff1f; &#xff08;1&#xff09;使用 Microsoft Word 导出 其实该…

doris:Insert Into Values

INSERT INTO VALUES 语句支持将 SQL 中的值导入到 Doris 的表中。INSERT INTO VALUES 是一个同步导入方式&#xff0c;执行导入后返回导入结果。可以通过请求的返回判断导入是否成功。INSERT INTO VALUES 可以保证导入任务的原子性&#xff0c;要么全部导入成功&#xff0c;要么…

C语言初阶--折半查找算法

目录 练习1&#xff1a;在一个有序数组中查找具体的某个数字n 练习2&#xff1a;编写代码&#xff0c;演示多个字符从两端移动&#xff0c;向中间汇聚 练习3&#xff1a;简单编写代码实现&#xff0c;模拟用户登录情景&#xff0c;并且只能登录三次 练习4&#xff1a;猜数字…

单片机(STC89C52)开发:点亮一个小灯

软件安装&#xff1a; 安装开发板CH340驱动。 安装KEILC51开发软件&#xff1a;C51V901.exe。 下载软件&#xff1a;PZ-ISP.exe 创建项目&#xff1a; 新建main.c 将main.c加入至项目中&#xff1a; main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…

Adobe的AI生成3D数字人框架:从自拍到生动的3D化身

一、引言 随着人工智能技术的发展,我们见证了越来越多创新工具的出现,这些工具使得图像处理和视频编辑变得更加智能与高效。Adobe作为全球领先的创意软件公司,最近推出了一项令人瞩目的新技术——一个能够将普通的二维自拍照转换成栩栩如生的三维(3D)数字人的框架。这项技…

Ansys Thermal Desktop 概述

介绍 Thermal Desktop 是一种用于热分析和流体分析的通用工具。它可用于组件或系统级分析。 来源&#xff1a;CRTech 历史 Thermal Desktop 由 C&R Technologies (CR Tech) 开发。它采用了 SINDA/FLUINT 求解器。SINDA/FLUINT 最初由 CR Tech 的创始人为 NASA 的约翰逊航…