☰
pgloader 快速上手:一条命令把 CSV、SQLite、MySQL 与远程数据迁入 PostgreSQL
2026/10/4 10:34:55 网站建设 项目流程
  • 数据工程
  • ETL
  • 数据集成
  • 数据库

【免费下载链接】pgloader

Migrate to PostgreSQL in a single command!

项目地址:https://gitcode.com/gh_mirrors/pg/pgloader
点击查看免费下载

pgloader 是 PostgreSQL 生态中专注"迁移"的命令行工具,其核心理念是"Migrate to PostgreSQL in a single command"。本文基于仓库中的 docs/quickstart.rst 编写,覆盖最常用的快速路径:命令行直接加载 CSV、从标准输入(STDIN)读取数据、加载 HTTP 远程文件、流式解压远程归档,以及 SQLite / MySQL 整库迁移和远程 DBF 归档导入。读完本文,你将掌握 pgloader 两种驱动模式中最简单的一种——完全由命令行参数驱动(SOURCE TARGET双参数模式),并理解每条命令背后的源码实现与适用前提。

一、两条使用路径:命令文件与命令行直驱

pgloader 提供了两种使用方式,理解它们的区别是快速上手的关键:

  • 命令文件(.load):pgloader 实现了一套类 SQL 的领域专用语言(DSL),支持LOAD ... FROM ... INTO ... WITH ...等子句,适合复杂场景(计算列、数据清洗、BEFORE/AFTER LOAD钩子)。语法骨架见 docs/command.rst。
  • 命令行直驱:当只有一个源和一个目标、且逻辑足够简单时,可以直接把信息放在命令行上,完全绕过命令文件。

从 入口实现 可以看到,当命令行参数恰好是两个时(=2 时),pgloader 会调用process-source-and-target把两个参数分别当作SOURCE和TARGET处理;而当参数多于两个时,则会把第一个参数当作命令文件(.load)解析。也就是说:

pgloader [ option ... ] SOURCE TARGET

这种"恰好两个参数"的模式就是快速入门的核心。命令行上没有命令文件,因此--type、--field、--with这些开关承担了传递额外信息的工作。

二、CSV 文件加载:最基础的入门命令

最简单的用例是把一个 CSV 文件加载到数据库里已经存在的表中:

pgloader --type csv \ --field id --field field \ --with truncate \ --with "fields terminated by ','" \ ./test/data/matching-1.csv \ postgres:///pgloader?tablename=matching

逐项拆解这条命令:

  • --type csv:强制指定源类型。命令行模式下 pgloader 需要知道如何解析源,--type是可选的"Force input source type"(见 main.lisp 选项定义)。CSV 文件没有内建的可探测类型,因此通常必须显式给出。
  • --field id --field field:声明源文件里每个字段的名字。--field是可重复选项(list t),每出现一次声明一个字段,顺序与文件中的列一一对应。除了--field id --field field这种逐个声明的方式,也可以把多个字段名用逗号合并进一个参数,如--field "usps,geoid,aland,awater"。
  • --with truncate:加载前对目标表执行TRUNCATE,保证目标表从空表开始(详见下文"WITH 选项速查")。
  • --with "fields terminated by ','":指定 CSV 分隔符为逗号。
  • ./test/data/matching-1.csv:源文件,仓库中真实存在(见 test/data/matching-1.csv)。
  • postgres:///pgloader?tablename=matching:目标连接串。注意表名通过 URI 的tablename参数传递,且目标表必须已经存在、结构能与数据匹配。

--field与--with的完整语法说明,见手册中的 CSV 参考文档。

从源码看,这条命令最终走的是 src/api.lisp 的process-source-and-target:它解析源串、目标串,把--with通过parse-cli-options转成选项列表,把--field通过parse-cli-fields转成字段定义,最后统一调用load-data进入加载流程。这意味着命令行直驱与命令文件两种模式最终汇合到同一套加载管线,行为一致。

目标表必须预先存在

与 SQLite/MySQL 整库迁移不同,CSV 加载不会自动建表。手册中给出的配套建表 SQL 如下(这是快速入门文档中唯一一段 SQL,务必完整保留):

create table districts_longlat ( usps text, geoid text, aland bigint, awater bigint, aland_sqmi double precision, awater_sqmi double precision, intptlat double precision, intptlong double precision );

三、从 STDIN 读取:管道与流式处理的基石

文件类数据源也可以从标准输入读取,把-(Unix 惯例中的标准输入)作为源参数即可:

pgloader --type csv \ --field "usps,geoid,aland,awater,aland_sqmi,awater_sqmi,intptlat,intptlong" \ --with "skip header = 1" \ --with "fields terminated by '\t'" \ - \ postgresql:///pgloader?districts_longlat \ < test/data/2013_Gaz_113CDs_national.txt

与上一例的区别:

  • -作为源:表示标准输入,数据由重定向<喂给 pgloader。
  • --field一次声明全部 8 个字段:用逗号分隔字段名,避免多次--field。
  • --with "skip header = 1":跳过文件第一行。该文件第一行通常是列名或版权说明,不能当作数据。测试数据 test/data/2013_Gaz_113CDs_national.txt 正是该例的源文件。
  • --with "fields terminated by '\t'":分隔符为制表符(\t在单引号内表示 Tab)。

流式加载压缩文件

STDIN 模式最大的价值在于与 Unix 管道组合,实现"边下载边解压边导入":

gunzip -c source.gz | pgloader --type csv ... - pgsql:///target?foo

注意:源参数-前的...表示完整的--field/--with参数集,实际执行时需按上例补全。操作系统负责网络与命令之间的流式缓冲,pgloader 负责把数据流持续灌入 PostgreSQL,全程无需落盘整个解压后的文件。

四、从 HTTP 加载 CSV:远程文件直接导入

CSV 文件位于远程 HTTP 地址时,pgloader 也能直接处理:

pgloader --type csv \ --field "usps,geoid,aland,awater,aland_sqmi,awater_sqmi,intptlat,intptlong" \ --with "skip header = 1" \ --with "fields terminated by '\t'" \ http://pgsql.tapoueh.org/temp/2013_Gaz_113CDs_national.txt \ postgresql:///pgloader?districts_longlat

这条命令与 STDIN 一节的命令几乎完全相同,只是把源从-换成了 HTTP URL。再次强调:

  • 第一行是表头,所以需要skip header = 1;
  • 全部字段合并进单个--field参数声明;
  • 目标连接串必须带tablename选项;
  • 目标表必须已存在且能容纳数据(即上一节的districts_longlat建表语句)。

另外,文档特别指出:同样的命令对同一份数据的归档版本(如 .gz)同样有效——pgloader 会在本地先抓取 HTTP 内容,识别出归档格式并解压,然后处理解压后的本地文件。

归档处理的实现细节

HTTP 抓取与解压的逻辑集中在 src/utils/archive.lisp:

  • http-fetch-file负责把远程文件下载到本地临时目录(*default-tmpdir*);
  • 支持归档类型由*supported-archive-types*定义,为:tar :tgz :gz :zip四种;
  • archive-type依据文件扩展名判定类型,expand-archive分别调用untar/gunzip/unzip解压。

因此"下载 → 解压 → 打开 → 发现 schema → 加载数据"是 pgloader 对远程归档的默认完整流程。

五、流式解压远程压缩 CSV:curl + gunzip + pgloader

当你的归档格式 pgloader 不支持,或环境中无法展开归档时,可以用经典管道把内容直接流式送入 PostgreSQL:

curl http://pgsql.tapoueh.org/temp/2013_Gaz_113CDs_national.txt.gz \ | gunzip -c \ | pgloader --type csv \ --field "usps,geoid,aland,awater,aland_sqmi,awater_sqmi,intptlat,intptlong" \ --with "skip header = 1" \ --with "fields terminated by '\t'" \ - \ postgresql:///pgloader?districts_longlat

这里curl从远程拉取 .gz 归档,gunzip -c就地解压并输出到 stdout,pgloader ... -从标准输入消费数据。OS 负责网络与命令进程间的流式缓冲,pgloader 则持续把数据流式写入 PostgreSQL。相比上一节的"先抓取再解压再处理",这种方式节省了中间落盘步骤,是处理大规模远程归档的推荐手法。

六、SQLite 整库迁移:schema 自动发现与类型转换

SQLite 迁移只需两条命令:

createdb newdb pgloader ./test/sqlite/sqlite.db postgresql:///newdb

pgloader会打开 SQLite 数据库,自动发现其表结构、索引与外键,把这些定义**cast(转换)**为 PostgreSQL 等价类型后迁移过来,随后迁移数据。仓库中test/sqlite/下提供了真实可用的样例库(如 test/sqlite/sqlite.db、Chinook 样例),可以拿来直接体验。

源码佐证:

  • SQLite 的 schema 探测走 src/sources/sqlite/sqlite-schema.lisp,其 introspection 依赖仓库内置的 PRAGMA 查询脚本,包括PRAGMA foreign_key_list(list-fkeys.sql)、PRAGMA index_list(list-table-indexes.sql)、PRAGMA index_info(list-index-cols.sql)等;
  • 类型转换规则由 src/sources/sqlite/sqlite-cast-rules.lisp 定义;
  • 未显式声明的自增主键索引也会被补全(add-unlisted-primary-key-index,见 sqlite-schema.lisp)。

与 CSV 不同,SQLite/MySQL 迁移时源是"数据库"而非"文件",pgloader 能自行探测 schema,因此不需要--type,也不需要预先建表。

七、MySQL 整库迁移:一行命令完成

MySQL 迁移同样是一条命令的事:

createdb pagila pgloader mysql://user@localhost/sakila postgresql:///pagila

pgloader 连接 MySQL 的 sakila 库,自动迁移其表结构(含索引、外键、视图等可迁移对象)、cast 数据类型并搬运数据。仓库中提供了完整可复现的测试场景,例如 tests/mysql/sakila 与 test/mysql 目录下的.load与.sql文件。

实现要点:MySQL 侧的类型转换规则见 src/sources/mysql/mysql-cast-rules.lisp,连接与 schema 探测在 src/sources/mysql/mysql-connection.lisp 与 src/sources/mysql/mysql-schema.lisp 中,源类型到加载代码的分派表定义于 src/api.lisp。

八、远程 DBF 归档:下载 → 解压 → 探测 → 导入

最后一个快速用例是 DBF(dBase)文件。pgloader 可以从 HTTP 下载归档、解压、打开并探测 schema,然后加载数据:

createdb foo pgloader --type dbf http://www.insee.fr/fr/methodes/nomenclatures/cog/telechargement/2013/dbf/historiq2013.zip postgresql:///foo

这里必须使用--type dbf:与 CSV 类似,pgloader 无法从给定的 HTTP URL 猜出数据源类型,因此需要命令行开关显式指定。仓库中的 DBF 测试数据与用例见 tests/dbf(含 dbf-31、dbf-8b、dbf-memo、reg2013 等场景)。

九、WITH 选项速查:快速路径可用的常用开关

命令行直驱模式下,--with是可重复的"Load options"(main.lisp),其解析器会把它映射为与命令文件WITH子句等价的选项。从 CSV 参考文档 与 CSV 解析器实现 可以确认,快速入门中最常用的包括:

选项作用
truncate加载前对目标表执行TRUNCATE,清空旧数据
skip header = N跳过输入文件开头的 N 行(表头/版权行)
csv header把跳过表头后的第一行当作 CSV 字段名列表
fields terminated by 'X'设置字段分隔符,支持普通字符、\t、0xNN十六进制形式
lines terminated by 'X'设置行结束符
fields optionally enclosed by 'X'设置引用/包围字符(默认双引号),如'\''或'0x27'
fields not enclosed字段不加引号,双引号按普通字符处理
fields escaped by backslash-quote设置转义字符
csv escape mode quote / following控制转义解析模式(默认quote)
trim unquoted blanks/keep unquoted blanks是否裁掉未加引号字段两侧的空白(默认裁剪)
date format '...'为日期/时间类型列统一指定解析模板
on error stop/on error resume next出错即停 / 出错继续
batch rows = R、batch size = ... MB、prefetch rows = ...批量行为控制
workers = W、concurrency = C、max parallel create index = I并行度控制

分隔符与引号字符的解析规则在 command-csv.lisp 中有精确定义:支持\t表示制表符、\表示反斜杠、0x加两位十六进制表示 ASCII 码,以及单引号转义写法。

十、命令行直驱的适用边界与注意事项

综合源码与文档,使用快速路径时请注意以下几点:

  1. 只有恰好两个位置参数时才会走SOURCE TARGET快速模式;否则第一个参数会被当作 .load 命令文件解析(main.lisp)。
  2. --type的适用性:CSV、DBF 等文件型源通常必须显式--type;SQLite/MySQL 这类数据库源可自动识别。
  3. 目标表存在性:CSV 加载要求目标表已存在且结构匹配;SQLite/MySQL 迁移则由 pgloader 自动建表。
  4. 表名传递:文件型源的目标表名通过 PostgreSQL 连接串的tablename参数指定,可以带 schema 前缀(如?tablename=geolite.blocks)。
  5. 当命令行参数与命令文件混用时:--type、--with、--field等选项在加载 .load 文件时会被忽略并给出提示(main.lisp),所以不要混用两种模式。

快速路径背后的统一入口load-data(src/api.lisp)会把命令行解析结果编译为加载代码并执行;从 api.lisp 的分派表 可见,csv、fixed、dbf、ixf、sqlite、mysql、mssql、pgsql 各源类型均有对应的加载代码生成函数——这意味着你在快速入门中学会的命令行直驱模式,可以平滑延伸到这些源类型。更复杂的场景(计算列、USING投影、BEFORE/AFTER LOAD钩子)则可以转向 docs/ref/csv.rst、docs/ref/sqlite.rst、docs/ref/mysql.rst 等参考文档,学习完整的 pgloader 命令语法。

  • 数据工程
  • ETL
  • 数据集成
  • 数据库

【免费下载链接】pgloader

Migrate to PostgreSQL in a single command!

项目地址:https://gitcode.com/gh_mirrors/pg/pgloader
点击查看免费下载
上一篇:如何在24小时内构建企业级数据可视化平台?
下一篇:Nuxt项目中使用vite-plugin-vue-inspector的完整教程与最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询