集成

PostgreSQL 作为标签数据源:一条查询,数千张标签

商品主数据存放在 PostgreSQL 中,标签也应从中生成。常见做法是导出 CSV,而导出刚完成,数据就已经过时了。更好的做法是:数据库始终作为数据源,标签打印直接查询它。

商品主数据存放在 PostgreSQL 中,标签也应从中生成。常见做法是导出 CSV,而导出刚完成,数据就已经过时了。更好的做法是:数据库始终作为数据源,标签打印直接查询它。

本文所述的一切同样适用于 MySQL 和 MariaDB——只是连接字符串的写法不同。

连接数据库的两种途径

通过代理:适用于数据库位于你自己网络内部的情况。zplCloudCli 代理向平台建立一条出站连接,在本地执行查询,只回传结果行。连接字符串只保存在你自己的机器上。无需任何入站端口。

直接从云端连接:适用于数据库本来就可以访问的情况——例如 Azure Database for PostgreSQL 或 Amazon RDS。此时由平台自行连接;连接字符串以 AES 加密形式存储在平台数据库中,仅在执行查询时才解密。

代理途径:注册服务器

代理可以通过启动选项、环境变量或文件来获知它的数据库。三种方式完全等效。

# 作为启动选项
zplcloud proxy --agent "Warehouse" \
  --postgres WMS="Host=pg.internal.lan;Database=wms;Username=zplcloud;Password=...;SSL Mode=Require"

# 或作为环境变量
export ZPLCLOUD_PG_WMS_CONNECTION="Host=pg.internal.lan;Database=wms;Username=zplcloud;Password=..."
zplcloud proxy --agent "Warehouse"

# 或作为 pgservers.json,放在二进制文件旁边或 ~/.zplcloud/ 下
# { "postgresServers": { "WMS": "Host=pg.internal.lan;Database=wms;Username=zplcloud;Password=..." } }

选项后面的名称(WMS)就是之后在选择器中显示的名称。MySQL 对应的选项是 --mysql,MariaDB 是 --mariadb,环境变量和文件也相应对应。

一条实践建议:创建一个专用数据库用户,只对标签所需的表授予只读权限。代理只会执行 SELECT,但一个无法执行更多操作的账户才是更可靠的保障。

创建数据源

数据中心 → 数据源 → 新建 下选择类型 PostgreSQL(代理)或 PostgreSQL (Cloud),然后选择代理和服务器。查询字段只接受单条 SELECT:

SELECT a.sku, a.description, a.ean, s.bin, a.best_before
FROM article a
JOIN stock s ON s.article_id = a.id
WHERE a.active = true

字段 会读取列信息而不加载任何数据——之后这些列即可在设计器中作为绑定使用。测试 用于检查连接。

查询可以包含什么

规则被刻意设得很严格,因为数据源的用途是读取,而不是写入:

  • 只允许单条 SELECTWITH,不能有分号、注释或多条语句。
  • 筛选值始终以参数形式传给数据库,绝不会拼接成文本。因此无法通过筛选行进行 SQL 注入。
  • 筛选、排序和 LIMIT/OFFSET 由数据库执行,而不是由平台执行。你的索引会发挥应有的作用。
  • 每次获取最多 1000 行,超时时间 15 秒。

这 1000 行并不是打印的上限:批量运行时,平台会在服务端逐块获取数据,一次最多可打印 50,000 张标签。内存中始终只保留一个数据块。

数据最终用在哪里

创建好的数据源可在所有需要数据的地方使用:

  • 打印视图——一个带表单的受保护 URL,用户可以按 EAN 搜索并打印返回的标签。
  • 批量打印——一次性处理查询的所有结果,分块发送到打印机。
  • 设计器——作为绑定数据,使预览显示真实值而不是占位符。

常见陷阱

  • “查询必须以 SELECT 开头。” 末尾多一个分号就足以触发此错误。删掉它即可。
  • 找不到列。 计算列需要命名:使用 SELECT price 1.19 AS gross,而不是 SELECT price 1.19
  • 连接失败。 可访问的 PostgreSQL 服务器通常强制要求 TLS:连接字符串中应包含 SSL Mode=Require
  • 代理不在线。 代理会自行维持连接。数据中心中的代理概览会显示有哪些代理在线,以及它们报告了哪些服务器。