psql 命令行工具

psql 是 PostgreSQL 的命令行前端。本页面介绍了 Spanner 的 PostgreSQL 页面支持的 psql 命令。如需了解如何与 psql 建立连接,请参阅将 psql 连接到 PostgreSQL 方言数据库

元命令

PostgreSQL 页面支持以下 psql 元命令类别:

  • 常规
  • 帮助
  • 查询缓冲区
  • 输入/输出
  • 基于条件
  • 参考信息(仅限某些 \d 命令)
  • 格式设置
  • 操作系统
  • 变量

不支持以下类别:

  • 连接
  • 大型对象

支持以下信息性命令:

命令 说明
\d 列出表(不包括系统表)
\d table 列出表列
\dt 列出所有架构中的表(详细)
\dt table 列出表(详细)
\dn 列出架构

会话管理语句

psql 通过 PGAdapter 与 Spanner 进行通信,后者使用 Spanner JDBC 驱动程序的核心引擎。驱动程序支持会话管理语句中所述的会话管理语句。因此,您可以将这些语句与 psql 搭配使用。

SQL 语句批处理

psql 和 PGAdapter 支持多语句 SQL 批次。如需批处理语句,请使用 psql -c 选项。此选项允许将一个或多个 SQL 或会话管理语句(用英文分号 (;) 分隔)作为单个执行请求传入。一个批次可以包含任何受支持的语句,并且可以混合使用 DDL、DML 和 DQL。

多语句批次在单个隐式事务块中执行。隐式事务块在批次结束时自动关闭。如果隐式事务块内发生任何错误,整个事务都会回滚。

系统支持明确的 BEGINCOMMIT 事务控制,但显式事务块不能包含 DDL 语句。

示例

DML

以下示例展示了如何批量提交 INSERT 语句。

psql -h localhost -p 5432 -c "INSERT INTO users (id, age, firstname) VALUES (1, 25, 'Alex'); \
 INSERT INTO users (id, age, firstname) VALUES (2, 31, 'Dana'); \
 INSERT INTO users (id, age, firstname) VALUES (3, 54, 'Izumi');"

以下示例展示了如何执行文件 insert_contacts.sql 中的 SQL 语句。

psql -h localhost -c "$(cat contacts_insert.sql)"

DDL

此示例提交了一批 ALTER TABLE 语句。

psql -h localhost -p 5432 test-db -c "ALTER TABLE users ADD col1 integer; \
 ALTER TABLE users ADD col2 text; ALTER TABLE users ADD col3 float8;"

用于导入数据的 COPY 命令

使用 COPY FROM STDIN 命令将文本文件或 CSV 文件中的数据导入 PostgreSQL 方言数据库。虽然仅支持 STDIN,但您可以使用 COPY 通过管道将文件导入 psql 进行导入。

您可以通过以下两种方式执行 COPY 命令:

  • 原子 COPY

    数据在单个事务中复制。这是默认值。 Spanner 的标准事务限制适用于事务。这意味着一次 COPY 操作最多可以包含 80,000 项更改或 100 MB 的数据。

  • 非原子 COPY

    如果文件包含超过 80,000 项更改或超过 100 MB,COPY 会自动在多个事务中拆分数据。

    如果在 COPY 期间遇到错误并且操作取消,某些行可能已经保留在数据库中。不会发生回滚。 这些事务是并行执行的,因此在 COPY 操作停止之前,导入文件中导致错误的行之后的数据可能会导入到数据库。

启用非原子 COPY

如需启用非原子 COPY,请在执行复制操作之前提交以下命令。

SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'

语法

COPY table_name [ ( column_name [, ...] ) ]
    FROM STDIN
    [ [ WITH ] ( option [, ...] ) ]

where option is one of:

    FORMAT format_name
    DELIMITER 'delimiter_character'
    NULL 'null_string'
    QUOTE 'quote_character'
    ESCAPE 'escape_character'
    HEADER [boolean]

and format_name is:
    {text|csv}

and delimiter_character is:
    [!-~] except ' " \

and null_string is:
    {a—z|A—Z|0—9|_}+

and quote_character is:
    [!-~] except ' " \

and escape_character is:
    [!-~] except ' " \

and boolean is:
    {TRUE|ON|1|FALSE|OFF|0}

该表必须已存在。如果未指定列列表,系统会复制表的所有列。

FORMAT 的默认值为 text

delimiter_character必须为单字节字符。默认情况下,文本格式使用制表符,CSV 格式则使用逗号。

NULL 指定表示 null 值的字符串。默认为文本格式的 \N(反斜杠 +N),CSV 格式默认为 \N(反斜杠 +N)。在您不希望区分 null 值和空字符串的情况下,可能更喜欢使用空字符串(即使是文本格式)。

QUOTE 指定引用数据值时要使用的引用字符。默认值为英文双引号。此值必须是单个单字节字符。只有在使用 CSV 格式时,才能使用此选项。

ESCAPE 指定在与 QUOTE 值匹配的数据字符之前显示的字符。默认值与 QUOTE 值相同(因此引号字符出现在数据中时会加倍)。此值必须是单个单字节字符。只有在使用 CSV 格式时,才能使用此选项。

HEADER 指示输入文件的第一条记录是否为标题(包含列名称)。默认值为 TRUE。

示例

以下示例将名为 mydata.txt 的文本格式文件的数据导入表 mytable。PGAdapter 必须正在运行。如需了解详情,请参阅启动 PGAdapter

cat mydata.txt | psql -h localhost -c "COPY mytable FROM STDIN;"

在下一个示例中,mydata.csv 采用 CSV 格式,其第一行是标题以及以英文逗号分隔的列名称。

cat mydata.csv | psql -h localhost \
  -c "COPY mytable FROM STDIN WITH (FORMAT csv, ESCAPE '~', HEADER TRUE);"

接下来的这个示例展示了如何启动非原子 COPY 操作。

cat mydata.txt | psql -h localhost \
  -c "SET SPANNER.AUTOCOMMIT_DML_MODE='PARTITIONED_NON_ATOMIC'" -c "COPY mytable FROM STDIN;"

问题排查

以下是一些常见的错误。

输入的语法无效

发生以下错误:

Invalid input syntax for type <type>:"<table_name>"

如果输入文件的标题行包含列名称,但未指定 HEADER 选项,则可能会发生此错误。

无效复制数据

发生以下错误:

Invalid COPY data: Row length mismatched. Expected <number> columns, but only found <number>

当输入文件中的行没有包含表中每一列的值(或 null)时,就会出现此错误。原因之一可能是 CSV 文件格式不正确,或者指定的分隔符选项(或默认分隔符)与文件中的实际分隔符不匹配。

后续步骤