#table #record #postgresql #schema #declarative #table-column #reference

bin+lib hldr

为 PostgreSQL 提供声明式和可表达的数据初始化

1 个不稳定版本

0.3.0 2024年4月17日

#18 in #table-column

MIT/Apache

490KB
2.5K SLoC

占位符

为 PostgreSQL 提供简单、声明式数据初始化

重要:占位符目前处于相当初级的 alpha 阶段,功能还不完整。

占位符力求通过提供一个功能强大的表达式 DSL,使生成、读取和维护测试数据成为一个愉快的体验,同时无需您设置语言运行时、工厂类等。

请参阅相应的 VS Code 扩展(同样处于 alpha 阶段),以查看语法高亮示例。

内容

  1. 概述
  2. 安装
  3. 使用方法
    1. 命令行选项
    2. 选项文件
  4. 特性
    1. 通用语法
    2. 字面值
    3. 注释
    4. 引号标识符
    5. 命名记录
    6. 引用
    7. 表别名
  5. 计划中的功能

概述

占位符语法主要受 SQL 启发,从直观上看,允许您将列 & 值对分组到记录中,这些记录按表组织,如果需要,还可以按模式组织。

当前的语言结构包括

  • 带有可选别名的模式与表分组声明
  • 匿名 & 命名记录
  • 原始字面值:布尔值、数字和文本字符串
  • 对同一记录中先前列或同一或任何其他表中的命名记录的引用
  • 内联注释

引用是占位符区别于其他声明性格式(例如 JSON)的主要因素,因为它们允许您简洁地引用在别处声明的值 从数据库返回的值,例如自动生成的主键!

计划中的其他 表达式结构 将进一步区分占位符,包括

  • 混合,用于定义可以包含在记录中的值集,类似于工厂 bot 中的 'traits'
  • 应用于表中的记录的默认值
  • 系列等,用于从范围或离散值列表创建多个记录

通用语法

General syntax

引用记录

References

安装

占位符目前必须从源代码编译,但针对常见平台的预编译二进制文件应 很快可用,并且理想情况下应能够通过 cargo 安装。

使用方法

占位符设计得易于使用。运行 hldr --helphldr -h 查看使用方法和所有可用选项。

USAGE:
    hldr [OPTIONS]

OPTIONS:
    -c, --database-conn <CONN>     Database connection string, either key/value pair or URI style
        --commit                   Commit the transaction
    -f, --data-file <DATA-FILE>    Path to the .hldr data file to load [default: place.hldr if not
                                   specified in options file]
    -h, --help                     Print help information
    -o, --opts-file <OPTS-FILE>    Path to the optional .toml options file [default: hldr-opts.toml]
    -V, --version                  Print version information

选项

最终,有三件事情需要注意。

1. 要加载的数据文件

默认情况下,hldr将寻找名为place.hldr的文件来加载,但可以使用--data-file <path>-f <path>选项加载任何其他文件。

# Load the `place.hldr` file by default
$ hldr

# Or specify a different file
$ hldr --data-file example.hldr
$ hldr -f ../example.hldr

2. 数据库连接

要指定数据库连接细节,可以通过--database-conn-c传递键值对或URI样式字符串。有关可用选项,请参阅postgres驱动程序文档。通常,选项与libpq类似。

# URI style
$ hldr --database-conn "postgresql://user:password@host:port/dbname"
$ hldr -c "postgresql://user:password@host:port/dbname"

# Key/value style - useful when including `options` eg. to set custom search path
$ hldr --database-conn "user=me password=passy options='-c search_path=schema1,schema2'"
$ hldr -c "user=me password=passy options='-c search_path=schema1,schema2'"

3. 事务是否应该提交或回滚

默认情况下,hldr会回滚事务以鼓励进行dry-run,因此可以通过传递--commit标志来覆盖此行为。

$ hldr
Rolling back changes, pass `--commit` to apply

$ hldr --commit
Committing changes

选项文件

指定命令行选项可能很方便(例如,在CI/CD中使用环境变量时),但对于本地开发来说可能特别繁琐。

为了使生活更加简单,可以在hldr-opts.toml文件中指定数据库连接和默认文件。

# hldr-opts.toml
#
# None of these values are required, and if supplied they will be overridden
# by any command-line options present

data_file = "../some-custom-file.hldr"
database_conn = "user=me password=passy options='-c search_path=schema1,schema2'"

如果hldr-opts.toml这个名字让人不高兴,可以指定自定义选项文件。

$ hldr --opts-file ../path/to/file.toml
$ hldr -o ../path/to/file.toml

重要:由于此文件可能依赖于环境并包含敏感信息,因此不应将其提交到版本控制

特性

字面值

目前,布尔值、数字和字符串只有字面值。

hldr目前将所有值解析为字符串,并使用简单查询协议将它们传递给Postgres,以便Postgres可以将值转换为适当的类型。

重要:这意味着hldr不会防止来自字符串值的SQL注入,尽管转向扩展查询协议正在计划中。

布尔值

布尔值必须是truefalse。与SQL不同,不支持如TRUEf这样的值。

数字

数字可以是整数或浮点值 - 占位符不会区分它们或尝试确定它们的大小。它们作为字符串传递,Postgres在每列基础上将它们强制转换为正确的类型,并且可以像1_00010_00.00_01那样进行格式化,只要没有连续的下划线,相邻的下划线与十进制符号,或者尾随的下划线。

字符串

文本字符串以单引号表示,就像在SQL中一样,可以用来表示charvarchartext或任何其他可以表示为文本的类型,例如数组、时间戳甚至可以表示为文本的自定义类型。

例如,整数数组目前将被写成'{1, 2, 3}'

转义单引号与SQL相同 - 只需将其加倍并使用 'you''ll be fine'. 目前不支持C风格转义字符串(例如:E'won\'t work')。

注释

注释与SQL类似,以 -- 开头,可以是换行符或尾随注释。目前不支持块注释,但将来会添加。

-- A newline comment
table (
  record (
      column value -- A trailing comment
  )
)

引号标识符

模式、表和列名称遵循Postgres规则,如果它们包含无效的标识符字符、与关键字同名等,则必须用双引号括起来。然而,即使未使用引号,它们也会作为引号标识符传递到数据库中,这意味着 MyTable 将作为 "MyTable" 传递,以便Postgres不会自动将其转换为小写。

schema "schema name with whitespace" (
  table "table" (
    "the answer" 41
  )
  table OtherTable ()
)

命名记录

记录本身可以命名,也可以是匿名的。命名记录允许在其他记录中引用它们的列(即使是那些由数据库填充且未在文件中声明的列)。

table person (
  -- A named record
  kevin (
    name 'Kevin'
  )
  -- Anonymous records
  _ (name 'A Different Kevin')
  (name 'Yet Another Kev')
)
table name (
  -- Record names only need to be unique within the given table
  kevin (
    value 'Kevin'
    origin 'Irish'
    derives_from 'Caoimhín'
  )
)

引用

命名记录允许在其他地方(无论是引用声明的列还是由数据库默认填充的列)引用它们。

存在几种支持的引用格式

格式 示例 将寻找
模式限定 @myschema.mytable.record.column 在模式下显式嵌套的表中先前声明的记录
表限定 @mytable.record.column 顶层表中先前声明的记录,不在任何模式下嵌套
记录限定 @record.column 与当前声明的记录处于同一表作用域中先前声明的记录
列限定 @column 在当前声明的记录中先前声明的列(注意:被引用的列不必须是字面值;它可以是对列或其他记录的另一个引用)

别名

模式和表也可以有别名来帮助缩短限定引用,在这种情况下,引用必须使用这些别名而不是全名。注意:同一表作用域内的记录限定引用仍无需使用名称或别名。

table person as p (
  p1 ( name 'Person 1' )

  -- References within the same scope do not NEED to qualify
  ( name @p1.name )

  -- But they can if desired. If this table was nested within a schema,
  -- the schema name would be required as well.
  ( name @p.p1.name )
)
table pet (
  -- The table alias is REQUIRED when referencing from another scope.
  ( person_id @p.p1.id )
)

计划中的功能

有关计划中的功能,请参阅标记为 增强 的问题。

依赖项

~8–18MB
~263K SLoC