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

如何用Perl自动批量导入JSON文件到DuckDB?无DBD驱动方案

实现思路

方案1:调用DuckDB命令行工具

Perl可以直接执行DuckDB的命令行命令,通过系统调用传递SQL语句,这是无需额外驱动的最直接方案。

示例代码:

use strict;
use warnings;

# 第一步:用第一个JSON文件创建表
my $create_table_cmd = qq{duckdb mydatabase.db -c "CREATE TABLE mytable AS SELECT * FROM read_json_auto('input1.json')"};
system($create_table_cmd) == 0 or die "创建表失败: $?";

# 第二步:遍历其余JSON文件插入数据
my @other_files = qw(input2.json input3.json ...); # 替换为你的目标文件列表
foreach my $file (@other_files) {
    # 转义文件路径中的特殊字符(如空格)避免命令出错
    my $escaped_file = quotemeta($file);
    my $insert_cmd = qq{duckdb mydatabase.db -c "INSERT INTO mytable SELECT * FROM read_json_auto('$escaped_file')"};
    system($insert_cmd) == 0 or die "插入文件 $file 失败: $?";
}

如果需要捕获命令输出或错误信息,可改用IPC::Run或IPC::Open3模块替代system,实现更精细的交互控制。

方案2:用Inline::C调用DuckDB的C API

若要避免频繁启动命令行进程、追求更高交互效率,可借助Perl的Inline::C模块直接调用DuckDB的C语言API,实现Perl与DuckDB的直接对接。

示例代码框架:

use strict;
use warnings;
use Inline 'C';

# 初始化DuckDB连接
my $db;
my $connection;
duckdb_open("mydatabase.db", \$db);
duckdb_connect($db, \$connection);

# 执行创建表的SQL
my $create_sql = "CREATE TABLE mytable AS SELECT * FROM read_json_auto('input1.json')";
my $result;
duckdb_query($connection, $create_sql, \$result);
duckdb_destroy_result($result);

# 遍历插入其他文件
my @other_files = qw(input2.json input3.json ...);
foreach my $file (@other_files) {
    my $insert_sql = "INSERT INTO mytable SELECT * FROM read_json_auto('$file')";
    duckdb_query($connection, $insert_sql, \$result);
    duckdb_destroy_result($result);
}

# 清理资源
duckdb_disconnect($connection);
duckdb_close($db);

__END__
__C__
#include <duckdb.h>

void duckdb_open(char *db_path, duckdb *out_db) {
    duckdb_open(db_path, out_db);
}

void duckdb_connect(duckdb db, duckdb_connection *out_conn) {
    duckdb_connect(db, out_conn);
}

void duckdb_query(duckdb_connection conn, char *sql, duckdb_result *out_result) {
    duckdb_query(conn, sql, out_result);
}

void duckdb_destroy_result(duckdb_result result) {
    duckdb_destroy_result(&result);
}

void duckdb_disconnect(duckdb_connection conn) {
    duckdb_disconnect(&conn);
}

void duckdb_close(duckdb db) {
    duckdb_close(&db);
}

使用该方案需确保系统已安装DuckDB开发库,且Inline::C能正确链接到该库。

方案3:合并JSON文件后一次性导入

若所有JSON文件格式一致,可先在Perl中将所有文件合并为一个符合要求的JSON文件,再一次性导入DuckDB,减少操作次数。此方案适合文件体积较小的场景,避免内存占用过高。

示例代码(合并为JSON数组):

use strict;
use warnings;
use JSON;

my @all_files = ('input1.json', 'input2.json', ...);
my @all_data;

foreach my $file (@all_files) {
    open my $fh, '<', $file or die "无法打开 $file: $!";
    my $content = do { local $/; <$fh> };
    my $data = decode_json($content);
    # 统一格式:单个对象转为数组元素,数组则直接展开
    push @all_data, ref $data eq 'ARRAY' ? @$data : $data;
    close $fh;
}

# 写入合并后的文件
open my $out_fh, '>', 'combined.json' or die "无法写入 combined.json: $!";
print $out_fh encode_json(\@all_data);
close $out_fh;

# 导入到DuckDB
system(qq{duckdb mydatabase.db -c "CREATE TABLE mytable AS SELECT * FROM read_json_auto('combined.json')"}) == 0 
    or die "导入合并文件失败: $?";

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:14:59