5. MySQL Shell 中的代码执行

本文章摘自《MySQL Shell 8.0 中文版.pdf》第5章,文档链接:https://www.modb.pro/doc/117504
本中文版文档采用 机翻及人工 相结合的方式,翻译自官方文档。

5. MySQL Shell 代码执行

5.1. Active Language


MySQL Shell 可以执行 SQLJavaScriptPython 代码,但一次只能执行一种语言。活动模式(Active Language)决定了当前可执行的语言:

  • 如果使用 SQL 模式,语句将被作为 SQL 处理,这意味着它们将被发送到 MySQL Server 执行。
  • 如果使用 JavaScript 模式,语句将作为 JavaScript 代码进行处理。
  • 如果使用 Python 模式,语句将作为 Python 代码处理。

:::alert-info
【Important】
从版本 8.0.18 开始,MySQL Shell 使用 Python 3。对于包含系统支持的 Python 3 安装的平台,MySQL Shell 使用最新可用版本,最低支持版本为 Python 3.4.3。对于不包含 Python 3 的平台,MySQL Shell 捆绑 Python 3.7.4MySQL Shell 保持与 Python 2.6Python 2.7 的代码兼容性,因此如果需要这些旧版本,则可以使用适当的 Python 版本从源代码构建 MySQL Shell
:::

当以交互模式运行 MySQL Shell 时,通过输入以下命令激活特定语言:\sql\js\py

以批处理模式运行 MySQL Shell 时,通过传递 --js--py--sql 选项来激活特定语言。如果未指定,则默认模式是 JavaScript

使用 MySQL Shell 将文件 code.sql 的内容作为 SQL 执行。

$> mysqlsh --sql < code.sql

使用 MySQL Shell 将文件 code.js 的内容作为 JavaScript 代码执行。

$> mysqlsh < code.js

使用 MySQL Shell 将文件 code.py 的内容作为 Python 代码执行。

$> mysqlsh --py < code.py

MySQL Shell 8.0.16 开始,可通过 \sql <SQL语句> 的方式在 JavaScriptPython 处于活动时,执行单个 SQL 语句。例如:

mysql-py> \sql select * from sakila.actor limit 3;

SQL 语句不需要任何额外的引号,并且语句分隔符是可选的。该命令仅接受单行中的单个 SQL 查询。使用这种方式,MySQL Shell 不会切换语言模式。执行 SQL 语句后,MySQL Shell 仍保持 JavaScriptPython 模式。

MySQL Shell 8.0.18 开始,可以在任何语言处于活动状态时通过 \system <OS命令>\! <OS命令> 的方式执行操作系统命令。例如:

mysql-py> \system echo Hello from MySQL Shell!

MySQL Shell 显示操作系统命令的输出,或者如果无法执行该命令则返回错误。

5.2. 交互式代码执行

MySQL Shell 的默认模式提供您在命令提示符下键入的数据库操作的交互式执行。这些操作可以用 JavaScriptPythonSQL 编写,具体取决于当前的 活动语言。执行时,操作结果显示在屏幕上。

与其他语言解释器一样,MySQL Shell 对于语法非常严格。例如,以下 JavaScript 代码片段打开与 MySQL Server 的会话,然后读取并打印集合中的文档:

var mySession = mysqlx.getSession('user:pwd@localhost'); var result = mySession.getSchema('world_x').getCollection('countryinfo').find().execute(); var record = result.fetchOne(); while(record){ print(record); record = result.fetchOne(); }

如上所示,调用 find() 函数后紧跟着的是 execute() 函数。CRUD 数据库命令只有在调用 execute() 时才会在 MySQL Server 上实际执行。不过,当以交互方式使用 MySQL Shell 时,只要按下 Return 键,就会隐式调用 execute()。然后,获取操作结果并将其显示在屏幕上。何时调用 execute() 的规则如下:

  • 当以这种方式使用 MySQL Shell 时,调用 execute() 成为可选项:

    • Collection.add()
    • Collection.find()
    • Collection.remove()
    • Collection.modify()
    • Table.insert()
    • Table.select()
    • Table.delete()
    • Table.update()
  • 如果将对象分配给变量,则自动执行将被禁用。在此情况下,必须显示调用 execute()

  • 当处理一行并且函数返回任何可用的 Result 对象时,Result 对象包含的信息将自动(无需调用 execute())显示在屏幕上。返回 Result 对象的函数包括:

    • SQL 执行和 CRUD 操作(如上所述)
    • mysqlmysqlx 模块中会话对象的事务处理和删除(drop)函数:-
      • startTransaction()
      • commit()
      • rollback()
      • dropSchema()
      • dropCollection()
      • ClassicSession.runSql()

根据上述规则,在 MySQL Shell 中以交互方式建立会话、查询、打印集合中的文档所需的语句如下:

mysql-js> var mySession = mysqlx.getSession('user:pwd@localhost'); mysql-js> mySession.getSchema('world_x').getCollection('countryinfo').find();

示例中,不需要调用 execute(),并且会自动打印 Result 对象。

5.2.1. 多行支持

PythonJavaScript 模式下,当语句块开始时(如函数定义、if/then 语句、for 循环等),会自动启用多行模式。在 SQL 模式下,当发出命令 \ 时,可启动多行模式。一旦启动多行模式,随后输入的语句即可被缓存。如:

mysql-sql> \ ... create procedure get_actors() ... begin ... select first_name from sakila.actor; ... end ...

当在另一种语言(JavaScriptPython)处于活动状态时,通过 \sql <SQL语句> 方式执行单个 SQL 语句时,不能使用多行模式。该命令仅接受单行上的单个 SQL 查询。

5.3. 代码自动补全

MySQL Shell 支持按 Tab 键自动补全代码。MySQL Shell 命令 可以在任何语言模式下自动补全。例如,键入 \con,按 Tab 键即可补全 \connect。根据当前 Active Language SQLJavaScriptPython 语言的关键字都可以自动补全。

自动补全支持以下文本对象:

  • SQL 模式下,自动补全功能会感知当前活动的 schema 名称、table 名称和 column 名称。
  • JavaScriptPython 模式中,自动补全功能可以识别对象成员,例如:
    • 全局对象名称,如 sessiondbdbashellmysqlmysqlx 等。
    • 全局对象的成员,如 session.connect()dba.configureLocalInstance() 等。
    • 用户定义的全局变量
    • 链式(chained)对象属性引用,如 shell.options.verbose
    • 链式(chainedX DevAPI 方法调用,如 col.find().where().execute().fetchOne()

默认情况下,自动补全功能处于启用状态,要更改此行为,请参阅 配置自动补全

激活自动补全功能后,如果光标前的文本正好有一个可能的匹配项,文本就会自动补全。如果自动补全功能发现多个可能的匹配项,则会发出蜂鸣声或使终端闪烁。如果再次按 Tab 键,将显示可能的补全列表。如果未找到匹配项,则不会自动补全。

5.3.1. SQL 自动补全

MySQL Shell 8.0.31 开始,在 SQL 模式中,可利用上下文感知功能,自动补全以下内容:

  • Schemas 数据库
  • Tables
  • Views 视图
  • Columns
  • 存储过程与函数
  • Triggers 触发器
  • Events 事件
  • Engines 存储引擎
  • User-defined functions 用户自定义函数
  • Runtime functions 运行时函数
  • Log file groups 日志文件组
  • 用户变量
  • 系统变量
  • 表空间
  • Users 用户
  • 字符集与排序规则
  • Plugins 插件

如果连接到 MySQL Server 实例但未选择 schema,自动补全功能可用于全局对象、字符集、存储引擎、 schema 等。如,在默认的 MySQL 安装中,除非提供 schema 名称中的一个或多个相关字符,否则 USE 会提示检测到的所有 schema 名称:

SQL > use information_schema mysql performance_schema sys

如果选择了一个 schemaMySQL Shell 就会加载额外的 schema 信息,并可用于自动补全(TablesEvents 等)。如果从一个 schema 切换到另一个 schema,从上一个 schema 加载的对象仍可用于 SQL 自动补全。但是,在会话期间添加的新对象在运行 \rehash 命令之前,都无法用于 SQL 自动补全。

要获取建议列表或从所选 schema 中补全部分单词,请输入初始片段并按 Tab2 次。例如:

  1. SQL 提示符下,输入片段:SE
  2. T​​ab2 次。以下建议将显示在您输入的下方:
SET SELECT
  1. SQL 提示符下,输入片段:SEL
  2. T​​ab2 次。片段自动完成为 SELECT

如果可能的结果有很多,系统会提示是否显示结果。例如:

Display all 118 possibilities? (y or n)

5.3.1.1. SQL 自动补全 API

自动补全 API 通过以下函数暴露给开发者:

  • JavaScript 模式:shell.autoCompleteSql(statement, options)
  • Python 模式:shell.auto_complete_sql(statement, options)

5.3.1.2. Statement 与 options

  • statement: "string"
    用于自动补全的部分 SQL 语句。

  • Options

    • serverVersion: "string"
      必选的。服务器语法版本。格式为:major.minor.patch。如 serverVersion:"8.0.31"
    • sqlMode: "string"
      必选的。要使用的 SQL Mode。以逗号分隔的字符串,如 sqlMode: "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"。有关详细信息,请参阅 https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html
    • statementOffset: number
      可选的。语句中插入符号从零开始的偏移位置。默认值是语句的长度。
    • uppercaseKeywords: [true|false]
      默认为 true,返回的关键字是否大写。
    • filtered: [true|false]
      默认为 true,是否应使用自动补全的前缀过滤结果中返回的明确候选名称。

该函数使用以下语法返回一个描述语句自动补全候选语句的字典,如下:

{ "context": { "prefix": string, "qualifier": list of strings, "references": list of dictionaries, "labels": list of strings, }, "keywords": list of strings, "functions": list of strings, "candidates": list of strings, }
  • context:自动补全操作的上下文。
  • prefix:自动补全的片段。
  • qualifier:如果有符合条件的名称,则显示。例如:
    • SELECT s:前缀为“s”,不存在限定符。
    • SELECT schema1.t:前缀为 ‘t’,限定符为 ['schema1']
    • SELECT schema1.table1.c:前缀为 ‘c’,限定符为 ['schema1','table1']
    • SELECT schema1.table1.column1 FR:前缀为“FR”,不存在限定符。
  • references:在语句中检测到的引用。
    • schemaschema 的名称。
    • table:语句中引用的表的名称。
    • alias:表的别名。
  • labels:标记块中的标签。
  • keywords:候选关键词建议。
  • functions:名称也是关键字的候选 MySQL 库(运行时)函数。
  • candidates:列出一个或多个受支持的候选对象。schemastablesviews 等。
JS > shell.autoCompleteSql("select * from ",{serverVersion: "8.0.30", sqlMode: "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"}) { "candidates": [ "schemas", "tables", "views" ], "context": { "prefix": "" }, "functions": [ "JSON_TABLE()" ], "keywords": [ "DUAL", "LATERAL" ] }

5.3.2. JavaScript 与 Python 自动补全

JavaScriptPython 模式中,要补全的字符串,从按下 Tab 键时的当前光标位置开始从右向左排列。方法调用内部的内容会被忽略,但语法必须正确。这意味着字符串、注释和嵌套方法调用都必须正确闭合和平衡。这样才能正确处理链式方法。例如,当发出:

print(db.user.select().where("user in ('foo', 'bar')").e

T​​ab 键将导致自动补全尝试完成文本 db.user.select().where().e 但此无效代码会产生未定义的行为。以 . 分隔的标记之间的任何空白符(包括换行符)都将被忽略。

5.3.3. 配置自动补全


默认情况下,自动补全引擎处于启用状态。本节介绍如何禁用自动补全以及如何使用 MySQL Shell\rehash 命令。自动补全使用 MySQL Shell 感知到的数据库名称对象缓存。启用自动补全后,此名称缓存会自动更新。例如,每当加载 schema 时,自动补全引擎都会根据 schema 中的文本对象更新名称缓存,以便可以自动补全表名称等。

可以通过如下方式,禁用此行为:

  • 使用 --no-name-cache 命令选项启动 MySQL Shell
  • 修改 shell.optionsautocomplete.nameCachedevapi.dbObjectHandles 键(keys),以使在 MySQL Shell 运行时禁用自动补全功能。

当自动补全名称缓存被禁用时,可以通过发出 \rehash 手动更新自动补全功能识别的文本对象。这会强制根据当前的活动模式(JavaScriptPythonSQL)重新加载名称缓存。

要在 MySQL Shell 运行时禁用自动补全功能,请使用以下的 shell.options 键(keys):

  • autocomplete.nameCache: boolean:启用(true)或禁用(false)自动补全名称缓存以供 SQL 使用。
  • devapi.dbObjectHandles: boolean:启用(true)或禁用(false)自动补全名称缓存以供 X DevAPI 数据库对象(如 db.mytabledb.mycollection)使用。

默认情况下,这两个键(keys)都为 true。如果指定 --no-name-cache 命令选项,则这两个键都被设置为 false

要在 MySQL Shell 运行时更改 SQL 的自动补全名称缓存,请发出:

shell.options['autocomplete.nameCache']=true

要在 MySQL Shell 运行时更改 JavaScriptPython 的自动补全名称缓存,请发出

shell.options['devapi.dbObjectHandles']=true

在任何语言模式(JavaScriptPythonSQL)中,都可以执行 \rehash 命令手动更新名称缓存。

5.4. 编辑代码

MySQL Shell\edit 命令(从 MySQL Shell 8.0.18 开始提供)在默认系统编辑器中打开命令进行编辑,然后在 MySQL Shell 中显示编辑后的命令以供执行。也可以使用简写形式 \e 或组合键 Ctrl-X Ctrl-E 调用该命令。如果为命令指定参数,则该参数将被放置在编辑器中。如果不指定参数,MySQL Shell 历史记录中的最后一个命令将被放置在编辑器中。

EDITORVISUAL 环境变量用于标识默认的系统编辑器。如果无法从这些环境变量中识别默认的系统编辑器,MySQL ShellWindows 上使用 notepad.exe,在其他平台上使用 vi。命令编辑在临时文件中进行,随后 MySQL Shell 会将其删除。

完成编辑后,必须保存文件并关闭编辑器,然后 MySQL Shell 会显示已编辑的文本,可以按 Enter 执行;如果不想继续,则可按 Ctrl-C 取消。

例如,此处用户使用一组自定义列运行 MySQL Shell 内置报告线程,然后在系统编辑器中打开命令以添加某些列的显示名称:

\show threads --foreground -o tid,cid,user,host,command,state,lastwait,lastwaitl \e \show threads --foreground -o tid=thread_id,cid=conn_id,user,host,command,state,lastwait=last_wait_event,lastwaitl=wait_length

5.5. 代码历史

MySQL Shell 中执行的代码会存储在历史记录中,然后可以使用 箭头键进行访问。你还可以使用增量历史搜索功能搜索历史记录。可以使用 Ctrl+R 向后搜索,或 Ctrl+S 向前搜索历史记录。搜索激活后,键入字符会搜索历史记录中与之匹配的字符串,并显示第一个匹配字符。使用 Ctrl+SCtrl+R 查找与当前搜索词匹配的其他字符。输入更多字符可进一步细化搜索。在搜索过程中,可以按箭头键从当前搜索结果开始继续浏览历史记录。按 Enter 键接受显示的匹配结果。使用 Ctrl+C 取消搜索。

MySQL Shell 配置选项 history.maxSize 可设置历史记录中存储条目的最大数量。默认为 1000。如果历史条目数超过了配置的最大值,最旧的条目将被移除并丢弃。如果 history.maxSize 设置为 0,则不存储任何历史条目。

默认情况下,历史记录不会在会话之间保存,因此当 MySQL Shell 时,当前会话中的历史记录就会丢失。通过启用 MySQL Shellhistory.autoSave 选项,可以在会话之间保存历史记录。如要使这一更改永久有效,请执行以下操作

mysqlsh-js> \option --persist history.autoSave=1

启用 history.autoSave 选项后,历史记录将存储在 MySQL Shell 配置路径中,在 LinuxmacOS 上是 ~/.mysqlsh 目录,在 Windows 上是 %AppData%\MySQL\mysqlsh 文件夹。通过定义环境变量 MYSQLSH_USER_CONFIG_HOME 可以在所有平台上重设该路径。保存的历史记录由 MySQL Shell 自动创建,只有所有者用户才能读取。如果无法读取或写入历史文件,MySQL Shell 会记录一条错误信息,并跳过读取或写入操作。在 MySQL Shell < 8.0.16,历史条目保存在一个历史文件中,该文件包含以所有 MySQL Shell语言发布的代码。在 MySQL Shell ≥ 8.0.16 中,历史记录按语言类型分别单独保存,文件名分别为 history.sqlhistory.jshistory.py

MySQL Shell 执行 \history 命令会按执行顺序显示历史条目及其编号,该编号可与 \history delete <entry_number> 命令一起使用。可以手动删除单个历史条目、指定数字范围的历史条目或历史记录的尾部。 也可以使用 \history clear 手动删除整个历史记录。 退出 MySQL Shell 时,如果配置选项 history.autoSavetrue,历史文件中保留的历史条目将被保存,它们的编号将被重置为从 1 开始。如果 shell.options["history.autoSave"] 配置选项为 false(默认值),历史文件将被清除。

只有在 MySQL Shell 交互模式输入的代码才会添加到历史记录中。间接或内部执行的代码,如在执行 \source 命令时执行的代码,不会添加到历史记录中。当执行多行代码时,历史记录条目中的换行字符会被去掉。如果多次执行同一代码,则只在历史记录中存储一次,从而减少重复。

可以使用 --histignore 命令选项指定不添加到历史记录中的条目。此外,在 SQL 模式下使用 MySQL Shell 时,可以配置不应添加到历史记录中的字符串。当使用 \sql 命令执行单条 SQL 语句时,如果另一种语言处于活动状态,也会应用此历史忽略列表。

默认情况下,与 IDENTIFIEDPASSWORD 匹配的字符串不会添加到历史记录中。要配置更多匹配字符串,请使用 --histignore 命令选项或 shell.options["history.sql.ignorePattern"]。可以指定以冒号(:)分隔的多个字符串。历史命令匹配使用不区分大小写的 glob 模式(glob pattern)匹配。支持的通配符有 *(匹配 0 个或更多字符)和 ?(精确匹配 1 个字符)。默认字符串指定为 “*IDENTIFIED*:*PASSWORD*”。

最后执行的语句始终可通过 箭头获得,即使对该语句已应用历史忽略列表。如果对最后执行的语句应用了历史忽略列表,那么一旦输入另一条语句,或在执行语句后立即退出 MySQL Shell,该语句就会从历史记录中删除。

5.6. 批处理代码执行

除了执行交互式代码之外,MySQL Shell 还提供从以下文件中执行批处理代码的功能:

  • 加载的以用于处理的文件。
  • 包含重定向到标准输入执行的代码的文件。
  • 将来自不同源的代码重定向到标准输入进行执行。

:::alert-info
【Tip】
作为批量执行文件的替代方法,还可以从终端控制 MySQL Shell,请参阅 API 命令行集成
:::

在批处理模式下,无法使用 交互式代码执行 中描述的命令逻辑,只能执行活动语言的有效代码。处理 SQL 代码时,使用以下逻辑逐条执行语句:读取/处理/打印结果。处理非 SQL 代码时,代码完全从输入源加载并作为一个单元执行。使用 --interactive(或-i)命令行选项可配置 MySQL Shell 处理输入源,就像在交互模式下发出输入源一样;这样就能在批处理中使用交互模式提供的所有功能。

:::alert-info
【Note】
在此情况下,无论是什么源,都会逐行读取并使用交互式管道进行处理。
:::

输入将根据 MySQL Shell 中选择的当前编程语言(默认为 JavaScript)进行处理。可以使用 MySQL ShelldefaultMode 配置选项更改默认编程语言。扩展名为 .js.py.sql 的文件总是以相应的语言模式处理,与默认编程语言无关。

此示例演示:如何从文件 code.js 加载 JavaScript 代码以进行批处理:

$> mysqlsh --file code.js

此示例演示:将文件 code.js 中的 JavaScript 代码重定向到标准输入来执行:

$> mysqlsh < code.js

此示例演示:如何将 SQL 代码重定向到标准输入以在 Linux 平台上执行:

$> echo "show databases;" | mysqlsh --sql --uri user@192.0.2.20:33060

:::alert-info
【Note】
要在 Windows 平台上运行此命令,必须删除 echo 命令中字符串周围的引号。
:::

MySQL Shell 8.0.22 开始,--pym 命令行选项可用于在 Python 模式下将指定的 Python 模块作为脚本执行。该选项的工作方式与 Python-m 命令行选项相同。

5.6.1. 可执行脚本

Linux 上,可以通过在首行包含 #!MySQL Shell 的完整路径和 --file 选项来创建与 MySQL Shell 一起运行的可执行脚本。例如:

#!/usr/local/mysql-shell/bin/mysqlsh --file print("Hello World\n");

脚本文件必须在文件系统中为可执行文件。运行脚本会调用 MySQL Shell 并执行脚本的内容。

5.6.2. 脚本中的 SQL 执行

X 协议会话中通常使用 sql() 函数执行 SQL 查询,该函数以字符串形式接收 SQL 语句,并返回一个 SqlExecute 对象。该对象用于绑定和执行 SQL 查询并返回结果。然而,传统 MySQL 协议会话中使用 runSql() 函数执行 SQL 查询,该函数接受 SQL 语句及其参数,将指定的参数绑定到指定的 SQL 查询中,然后单步执行查询,并返回结果。

如果需要创建独立于用于连接 MySQL Server 协议的 MySQL Shell 脚本,MySQL Shell 提供了用于 X 协议的 session.runSql() 函数,其工作方式与传统 MySQL 协议会话中的 runSql() 函数相同。在 MySQL Shell 中,只能使用这个函数来代替 sql(),这样你的脚本就能在 X 协议会话或传统 MySQL 协议会话中运行。Session.runSql() 返回一个 SqlResult 对象,该对象与传统 MySQL 协议函数返回的 ClassicResult 对象的规格一致,因此可以用同样的方式处理结果。

:::alert-info
【Note】
Session.runSql()JavaScriptPython 中的 MySQL Shell X DevAPI 实现所独有的,并非标准 X DevAPI 的一部分。
:::

要浏览查询结果,可以使用 fetchOneObject() 函数,该函数适用于传统的 MySQL 协议和 X 协议。该函数以脚本对象的形式返回下一个结果。列名用作字典中的键(如果是有效标识符,则用作对象属性),行值用作字典中属性值。对对象所作的更新不会保留在数据库中。

如,MySQL Shell 脚本中的这段代码可与 X 协议会话或传统 MySQL 协议会话配合使用,以检索和输出给定国家/地区的城市名称:

var resultSet = mySession.runSql("SELECT * FROM city WHERE countrycode = ' AUT'"); var row = resultSet.fetchOneObject(); print(row['Name']);

5.7. 输出格式

MySQL Shell 可以以表格、Tab 制表符或垂直格式打印结果,也可以以美化或原始的 JSON 格式打印结果。从 MySQL Shell 8.0.14 开始,MySQL Shell 配置选项 resultFormat 可用于为所有会话或仅当前会话指定永久的默认输出格式,更改后立即生效。有关设置 MySQL Shell 配置选项的说明,请参阅 配置 MySQL Shell 选项。另外,也可以在启动时使用命令行选项 --result-format 或其别名(--table--tabbed--vertical)来指定会话的输出格式。有关命令行选项的列表,请参阅 mysqlsh

如果未指定 resultFormat 配置选项,当 MySQL Shell 处于交互模式时,打印结果集的默认格式是格式化的表格;当 MySQL Shell 处于批处理模式时,打印结果集的默认格式是 Tab 制表符分隔的输出。使用 resultFormat 选项设置默认格式时,该默认格式适用于交互模式和批处理模式。

MySQL Shell 函数 shell.dumpRows() 可以将查询返回的结果集格式化为 MySQL Shell 支持的任何输出格式,并将其转储到控制台。

为了帮助 MySQL Shell 与外部工具集成,从命令行启动 MySQL Shell 时,可以使用 --json 选项控制所有 MySQL Shell 输出的 JSON 封装(wrapping):

  • 当开启 JSON 封装时,MySQL Shell 会生成美化的 JSON(默认)或原始 JSON,并忽略 resultFormat 配置选项的值。
  • 当关闭 JSON 封装或未请求会话时,会按照 resultFormat 配置选项指定的格式正常输出结果集。

outputFormat 配置选项现已弃用。该选项结合了 JSON 封装(wrapping)和结果打印功能。如果在 MySQL Shell 配置文件或脚本中仍指定该选项,则行为如下:

  • 若指定 outputFormatjsonjson/raw,则 outputFormat 分别使用美化或原始 JSON 激活 JSON 封装。
  • 若指定 outputFormattabletabbedvertical,则 outputFormat 会关闭 JSON 封装并将会话的 resultFormat 配置选项设置为适当的值。

5.7.1. Table 格式

MySQL Shell 处于交互模式时,默认使用 table 格式打印结果集。查询结果以格式化表格形式呈现,以便更好地查看并帮助分析。

要在批处理模式下获得此输出格式,请使用 --result-format=table 命令行选项(或其别名 --table)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 table

MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','table') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") +------+------------+-------------+---------------+-------------------------+ | ID | Name | CountryCode | District | Info | +------+------------+-------------+---------------+-------------------------+ | 1523 | Wien | AUT | Wien | {"Population": 1608144} | | 1524 | Graz | AUT | Steiermark | {"Population": 240967} | | 1525 | Linz | AUT | North Austria | {"Population": 188022} | | 1526 | Salzburg | AUT | Salzburg | {"Population": 144247} | | 1527 | Innsbruck | AUT | Tiroli | {"Population": 111752} | | 1528 | Klagenfurt | AUT | Kärnten | {"Population": 91141} | +------+------------+-------------+---------------+-------------------------+ 6 rows in set (0.0030 sec)

5.7.2. Tab 分隔格式

在批处理模式下运行 MySQL Shell 时,默认使用 Tab 制表符格式打印结果集,以便为自动分析提供更好的输出。

要在交互模式下获得此输出格式,请使用 --result-format=tabbed 命令行选项(或其别名 --tabbed)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 tabbed

MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','tabbed') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") ID Name CountryCode District Info 1523 Wien AUT Wien {"Population": 1608144} 1524 Graz AUT Steiermark {"Population": 240967} 1525 Linz AUT North Austria {"Population": 188022} 1526 Salzburg AUT Salzburg {"Population": 144247} 1527 Innsbruck AUT Tiroli {"Population": 111752} 1528 Klagenfurt AUT Kärnten {"Population": 91141} 6 rows in set (0.0041 sec)

5.7.3. 垂直格式

垂直格式打印结果集,与 \G 查询终止符用于 SQL 查询时的方式相同。当单个数据行过长时,垂直格式更具可读性。

要获得此输出格式,请使用 --result-format=vertical 命令行选项(或其别名 --vertical)启动 MySQL Shell,或将 MySQL Shell 配置选项 resultFormat 设置为 vertical

MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','vertical') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") *************************** 1. row *************************** ID: 1523 Name: Wien CountryCode: AUT District: Wien Info: {"Population": 1608144} *************************** 2. row *************************** ID: 1524 Name: Graz CountryCode: AUT District: Steiermark Info: {"Population": 240967} *************************** 3. row *************************** ID: 1525 Name: Linz CountryCode: AUT District: North Austria Info: {"Population": 188022} *************************** 4. row *************************** ID: 1526 Name: Salzburg CountryCode: AUT District: Salzburg Info: {"Population": 144247} *************************** 5. row *************************** ID: 1527 Name: Innsbruck CountryCode: AUT District: Tiroli Info: {"Population": 111752} *************************** 6. row *************************** ID: 1528 Name: Klagenfurt CountryCode: AUT District: Kärnten Info: {"Population": 91141} 6 rows in set (0.0027 sec)

5.7.4. JSON 格式输出

MySQL Shell 提供了许多 JSON 格式选项来打印结果集:

  • jsonjson/pretty
    这些选项都会生成打印美化的 JSON

  • ndjsonjson/raw
    这些选项都会生成由换行符分隔的原始 JSON

  • json/array
    此选项生成包装在 JSON 数组中的原始 JSON

可以通过使用 --result-format=value 命令行选项启动 MySQL Shell 或设置 MySQL Shell 配置选项 resultFormat 来指定这些输出格式。

在批处理模式下,为了帮助将 MySQL Shell 与外部工具集成,可以在从命令行启动 MySQL Shell 时使用 --json 选项来控制所有输出的 JSON 封装。当 JSON 封装打开时,MySQL Shell 生成美化的 JSON(默认)或原始 JSON,并且忽略 MySQL Shell 配置选项 resultFormat 的值。有关说明,请参阅 JSON 包装

  • jsonjson/pretty
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','json') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") { "ID": 1523, "Name": "Wien", "CountryCode": "AUT", "District": "Wien", "Info": { "Population": 1608144 } } { "ID": 1524, "Name": "Graz", "CountryCode": "AUT", "District": "Steiermark", "Info": { "Population": 240967 } } { "ID": 1525, "Name": "Linz", "CountryCode": "AUT", "District": "North Austria", "Info": { "Population": 188022 } } { "ID": 1526, "Name": "Salzburg", "CountryCode": "AUT", "District": "Salzburg", "Info": { "Population": 144247 } } { "ID": 1527, "Name": "Innsbruck", "CountryCode": "AUT", "District": "Tiroli", "Info": { "Population": 111752 } } { "ID": 1528, "Name": "Klagenfurt", "CountryCode": "AUT", "District": "Kärnten", "Info": { "Population": 91141 } } 6 rows in set (0.0031 sec)
  • ndjsonjson/raw
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','ndjson') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") {"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}} {"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}} {"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}} {"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}} {"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}} {"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}} 6 rows in set (0.0032 sec)
  • json/array
MySQL localhost:33060+ ssl world_x JS > shell.options.set('resultFormat','json/array') MySQL localhost:33060+ ssl world_x JS > session.sql("select * from city where countrycode='AUT'") [ {"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}}, {"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}}, {"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}}, {"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}}, {"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}}, {"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}} ] 6 rows in set (0.0032 sec)

5.7.5. JSON 封装

为了帮助将 MySQL Shell 与外部工具集成,可以在从命令行启动 MySQL Shell 时使用 --json 选项来控制所有 MySQL Shell 输出的 JSON 封装。--json 选项仅对指定它的 MySQL Shell 会话有效。

指定 --json--json=pretty--json=raw 将打开会话的 JSON 封装。使用 --json=pretty 或未指定任何值,会生成打印美化的 JSON。使用 --json=raw,生成原始 JSON

打开 JSON 封装后,在配置文件或命令行(使用 --result-format 选项或其别名之一)中为 MySQL Shell 配置选项 resultFormat 指定的任何值都将被忽略。

指定 --json=off 将关闭会话的 JSON 封装。当关闭 JSON 封装或会话未请求 JSON 封装时,结果集将以 MySQL Shell 配置选项 resultFormat 指定的格式正常输出。

  • --json--json=pretty
$> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json --sql --uri user@localhost:33060 or $> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json=pretty --sql --uri user@localhost:33060 { "hasData": true, "rows": [ { "ID": 1523, "Name": "Wien", "CountryCode": "AUT", "District": "Wien", "Info": { "Population": 1608144 } }, { "ID": 1524, "Name": "Graz", "CountryCode": "AUT", "District": "Steiermark", "Info": { "Population": 240967 } }, { "ID": 1525, "Name": "Linz", "CountryCode": "AUT", "District": "North Austria", "Info": { "Population": 188022 } }, { "ID": 1526, "Name": "Salzburg", "CountryCode": "AUT", "District": "Salzburg", "Info": { "Population": 144247 } }, { "ID": 1527, "Name": "Innsbruck", "CountryCode": "AUT", "District": "Tiroli", "Info": { "Population": 111752 } }, { "ID": 1528, "Name": "Klagenfurt", "CountryCode": "AUT", "District": "Kärnten", "Info": { "Population": 91141 } } ], "executionTime": "0.0067 sec", "affectedRowCount": 0, "affectedItemsCount": 0, "warningCount": 0, "warningsCount": 0, "warnings": [], "info": "", "autoIncrementValue": 0 }
  • --json=raw
$> echo "select * from world_x.city where countrycode='AUT'" | mysqlsh --json=raw --sql --uri user@localhost:33060 {"hasData":true,"rows":[{"ID":1523,"Name":"Wien","CountryCode":"AUT","District":"Wien","Info":{"Population":1608144}},{"ID":1524,"Name":"Graz","CountryCode":"AUT","District":"Steiermark","Info":{"Population":240967}},{"ID":1525,"Name":"Linz","CountryCode":"AUT","District":"North Austria","Info":{"Population":188022}},{"ID":1526,"Name":"Salzburg","CountryCode":"AUT","District":"Salzburg","Info":{"Population":144247}},{"ID":1527,"Name":"Innsbruck","CountryCode":"AUT","District":"Tiroli","Info":{"Population":111752}},{"ID":1528,"Name":"Klagenfurt","CountryCode":"AUT","District":"Kärnten","Info":{"Population":91141}}],"executionTime":"0.0117 sec","affectedRowCount":0,"affectedItemsCount":0,"warningCount":0,"warningsCount":0,"warnings":[],"info":"","autoIncrementValue":0}

5.7.6. 结果元数据

执行操作时,除了返回任何结果之外,还会返回一些附加信息。当满足以下任一条件时,附加信息包括受影响的行数、警告、持续时间等信息:

  • JSON 格式用于输出
  • MySQL Shell 以交互模式运行。

JSON 格式用于输出时,元数据将作为 JSON 对象的一部分返回。在交互模式下,元数据在结果之后打印。

5.8. API 命令行集成

MySQL Shell 通过 API 命令行集成提供了大部分功能,使用的语法无需打开交互界面即可访问对象及其函数。这使您能够轻松地将 mysqlsh 与其他工具集成。例如,如果想使用 bash 脚本自动创建 InnoDB Cluster,则可以使用命令行集成来调用 AdminAPI 操作。此功能类似于使用 --execute 选项,但命令行集成使用简化的参数语法,减少了终端可能需要的引用和转义。与批处理模式不同,命令行集成是无状态的。这意味着执行返回对象无法供后续操作使用的操作。命令行集成调用操作或全局对象的函数,然后返回。

5.8.1. 命令行集成概述

本节提供命令行集成的概述和一些基本使用示例。有关更多详细信息,请参阅 命令行集成详细信息

以下内置的 MySQL Shell 全局对象可在命令行集成中使用:

  • session
    表示当前的全局会话。

  • db
    当指定了默认数据库(schema),并使用 X 协议建立了全局会话时,db 对象可用,并表示该默认的 schema。。请参阅 https://dev.mysql.com/doc/refman/8.0/en/document-store.html

  • cluster
    代表一个 InnoDB Cluster

  • clusterset
    代表一个 InnoDB ClusterSet

  • rs
    代表一个 InnoDB ReplicaSet

  • shell
    提供对各种 MySQL Shell 函数的访问。如用于配置 MySQL Shell 选项的 shell.options。请参阅 配置 MySQL Shell 选项

  • util
    提供了对 MySQL Shell 工具的访问,如升级检查工具(utl.checkForServerUpgrade())、JSON 导入工具(util.importJSON())和并行表导入工具(util.importTable())。请参阅 MySQL Shell 工具

有关更多信息,请参阅 MySQL Shell 全局对象

5.8.1.1. 命令行集成语法

:::alert-info
【Important】
MySQL Shell 8.0.32 开始,MySQL Shell 默认读取 MySQL Server 选项文件和登录路径。因此,如果连接到使用选项文件的 MySQL Server,默认情况下将使用该选项文件,并尝试使用该配置创建全局会话。如果不想使用选项文件,则必须为命令行指定 --no-defaults
:::

可以通过启动 mysqlsh 工具并传入特殊的 -- 选项来访问命令行集成。当以这种方式启动 MySQL Shell 时,-- 表示选项列表(例如要连接的服务器、要使用的语言等)的结束,-- 之后的所有内容都将传递给命令行集成。命令行集成支持特定语法,该语法基于 MySQL Shell 交互界面中使用的对象和方法。要使用命令行集成语法执行操作,请在终端中执行以下操作:

mysqlsh [options] -- [shell_object]+ object_method [arguments]

语法元素如下:

  • shell_object
    是一个映射到 MySQL Shell 全局对象的字符串。命令行集成支持嵌套对象。要调用嵌套对象中的函数,请提供以空格分隔的层次结构中的对象列表,以找到所需的对象。

  • object_method
    是最后一个 shell_object 提供的方法名称。方法名称可以按照 JavaScriptPython 命名约定,或替代的命令行集成友好格式提供,其中所有已知函数都使用小写字母,且单词之间用连字符分隔。object_method 的名称会自动从标准 JavaScript 风格的 camelCase(驼峰式) 名称转换而来。例如,createCluster 变成 create-cluster

  • arguments
    参数是调用 object_method 时传递给它的参数。

shell_object 必须与公开的全局对象之一匹配,并且任何嵌套对象必须是列表中前一个对象的子对象。 object_method 必须与列表方法中最后一个对象之一匹配,并且必须以有效格式定义(JavaScriptPython 或命令行友好格式)。如果它们与有效对象及其方法不一致,MySQL Shell 将以状态码 10 退出。请参阅 MySQL Shell 命令行集成示例

5.8.1.2. 命令行集成中可用的对象

要找出命令行集成中可用的对象和方法,最好查询正在使用的 MySQL Shell。因为除了与 MySQL Shell 捆绑的标准对象之外,插件的其他对象也可能被暴露。

可通过如下方式,获取命令行集成支持的对象列表。这将显示对象列表以及该对象提供的内容的简短描述。

$ mysqlsh -- --help

获取对象的命令行集成中可用的函数列表:

$ mysqlsh -- object --help

有关详细信息,请参阅 命令行帮助

5.8.1.3. 命令行集成参数语法

参数列表是可选的,所有参数必须遵循本节所述的适合命令行使用的语法。特殊字符(如空格或引号)和引号在传递给 MySQL Shell 之前会由系统 shellbashcmd 等)处理。如果你不熟悉你的系统 shell 在解析命令时如何处理这些字符序列,你应该尽量避免使用它们。例如,要传递一个带引号的参数,如 "list, of, names",仅在命令行中使用这种语法是不够的。需要使用系统的 shell 语法来转义这些引号("")。否则,MySQL Shell 可能接收不到实际的引号。请参阅 定义参数

在参数列表中可以使用两种类型的参数:匿名参数命名参数。匿名参数用于定义简单类型的参数,如字符串、数字、布尔值和空值。命名参数用于定义列表参数值和字典参数中的选项,它们是 键值对,其中的值是简单类型。它们的使用必须遵循以下模式(pattern):

[positional_argument | named_argument]*

语法的所有部分都是可选的,并且可以按任何顺序给出。然后,这些参数将按以下顺序转换为传递给方法调用的参数:

  • 来自列表的命名参数会将值附加到产生该命名参数的列表参数中
  • 来自字典的命名参数会将值添加到产生该命名参数的字典参数中
  • 如果字典参数中存在未定义明确选项的参数,则该参数会接受不属于另一个 ListDictionary 参数的任何已命名参数。
  • 为函数调用提供的任何其余参数都将按照提供的顺序进行处理

5.8.1.4. 命令行集成示例

与使用 --execute 选项相比,使用命令行集成调用 MySQL Shell API 函数更简单、更省事。。以下示例展示了如何使用此功能:

  • 检查 MySQL Server 实例是否适合升级,并将结果以 JSON 格式返回,以便进一步处理:
$ mysqlsh -- util check-for-server-upgrade --user=root --host=localhost --port=3301 --password='password' --outputFormat=JSON --config-path=/etc/mysql/my.cnf

MySQL Shell 交互模式下的等效命令:

mysql-js> util.checkForServerUpgrade({user:'root', host:'localhost', port:3301}, {password:'password', outputFormat:'JSON', configPath:'/etc/mysql/my.cnf'})
  • 部署端口为 1234InnoDB Cluster 沙箱实例,并指定用于连接的密码:
$ mysqlsh -- dba deploy-sandbox-instance 1234 --password=password

MySQL Shell 交互模式下的等效命令:

mysql-js> dba.deploySandboxInstance(1234, {password: password})
  • 使用监听端口 1234 的沙盒实例创建 InnoDB Cluster,并指定名称 mycluster
$ mysqlsh root@localhost:1234 -- dba create-cluster mycluster

MySQL Shell 交互模式下的等效命令:

mysql-js> dba.createCluster('mycluster')
  • 使用监听端口 1234 的沙盒实例检查 InnoDB Cluster 的状态:
$ mysqlsh root@localhost:1234 -- cluster status

MySQL Shell 交互模式下的等效命令:

mysql-js> cluster.status()
  • 配置 MySQL Shell 以打开命令历史记录:
$ mysqlsh -- shell options set_persist history.autoSave true

MySQL Shell 交互模式下的等效命令:

mysql-js> shell.options.set_persist('history.autoSave', true);

5.8.2. 命令行集成详情

5.8.2.1. API 函数的命令行集成

MySQL Shell 提供了暴露不同功能的全局对象,例如用于InnoDB ClusterInnoDB ReplicaSet 管理操作的 dba、用于实用函数的 util 等。全局对象提供从 MySQL Shell 脚本模式调用的功能。除了交互式 MySQL Shell 集成之外,还可以使用命令行集成,直接从终端调用对象函数,从而轻松与其他工具集成。

在交互模式下使用 MySQL Shell 附带的 API 时,典型的函数语法如下:

object.functionName(parameter1, parameter2, ..., parameterN)

这些参数定义了向 API 函数提供数据的顺序。在大多数情况下,API 函数希望参数采用特定的数据类型,但也有少数例外情况,即一个特定参数可以处理多种数据类型。API 函数中参数使用的数据类型可以是以下类型之一:

  • Scalars
    标量,如 string, numbers, booleans, null

  • Lists
    列表

  • Dictionary
    key-value 键值对,其中 key 是字符串

  • Objects
    对象

列表参数通常被限制为包含预定义数据类型的元素,例如字符串列表,但是,可能存在支持不同数据类型的项目的列表参数。

字典参数接受 键值对,其中键(key)是字符串。与键关联的值通常应该是预定义的数据类型。但是,在某些情况下,同一键的值可能支持不同的数据类型。因此,字典参数可以是以下类型之一:

  • 允许使用预定义的键值对集,在这种情况下,指定不在预定义集中的键会导致错误。
  • 不存在预定义的键值对集,字典接受任何键

换句话说,某些字典参数指定了哪些键是有效的。对于这些参数,尝试使用该组之外的键会导致错误。当不存在预定义的值集时,可以使用任何数据类型的任何值。字典参数如果没有预定义的键列表,则可以接受任何键值对,只要该键不在另一个字典参数的预定义集中。

要使用命令行集成调用全局对象暴露的 API 函数,而无需在 MySQL Shell 中启动交互会话,就必须以正确的方式提供所需的数据。这包括定义调用 API 函数的方式,以及将其参数从命令行参数映射到 API 参数的方式。

:::alert-info
【Important】
命令行集成并未公开所有 MySQL Shell 函数。例如,诸如 dba.getCluster() 等函数依赖于返回一个对象,然后在进一步操作中使用该对象。命令行集成不会公开此类操作。

同样,MySQL Shell 命令行集成也不支持将对象作为参数。任何带有对象类型参数的 API 函数都不能与命令行集成一起使用。对象的生命周期仅限于创建它的 MySQL Shell 调用的生命周期。由于 mysqlsh 在通过此 API 语法执行对象方法后会立即退出,因此从 API 调用接收或传入的任何对象都会立即退出作用域。在开发希望与命令行集成的 MySQL Shell 插件时,应考虑到这一点。
:::

从命令行调用 MySQL Shell API 函数的一般格式是:

$ mysqlsh [shell options] -- [shell_object]+ object_function [anonymous_arguments|named arguments]*
  • shell_object:指定一个全局对象,其中包含供命令行使用的公开函数。支持以空格分隔的列表嵌套对象。
  • object_function:指定应执行的最后一个 shell_objectAPI 函数。
  • [anonymous_arguments|named arguments]*:指定传递给 object_function 调用的参数

对于大多数可用的 API,都需要一个对象,例如:

$ mysqlsh -- shell status

但对于嵌套对象,必须指明对象列表。例如,要调用 shell.options 暴露的函数,如 setPersist(optionName, value),请使用以下语法:

$ mysqlsh -- shell options set-persist defaultMode py

MySQL Shell 插件中定义的嵌套对象可能会发生类似的情况。

传递给函数的参数可以分为以下类型:

  • 匿名参数:它们是提供给命令的原始值。例如,在以下调用中的 1onetrue 是匿名参数:
$ mysqlsh -- object command 1 one true
  • 命名参数:以 --key=value 形式提供的键值对。例如,在以下调用中,--sample--path 是命名参数:
$ mysqlsh -- object command 1 one true --sample=3 --path=some/path

鉴于参数的这种划分,从命令行集成调用 API 函数的一般格式是:

$ mysqlsh [shell options] -- object command [anonymous arguments][named arguments]

匿名参数的顺序很重要,因为它们按位置方式处理的。另一方面,命名参数可以出现在任何地方,因为它们会首先被处理,并与相应的参数关联。命名参数被处理完毕后,匿名参数将会以位置方式处理。

5.8.2.2. 定义参数

https://dev.mysql.com/doc/mysql-shell/8.0/en/cli-integration-defining-arguments.html

MySQL Shell API 函数的命令行集成 中所述,MySQL Shell 中的大多数 API 都期望所提供的参数具有特定的数据类型。可以使用 JSON 规范提供命令行参数中的值,但需要注意以下事项。某些终端会对数据进行预处理,可能会影响向 MySQL Shell 提供数据的方式,这取决于所使用的终端。例如:

  • 如果发现空格,某些终端会分割参数。
  • 分割逻辑可能会忽略连续的空格。
  • 引号可以被删除。

MySQL Shell 会根据运行终端提供的值进行解释,因此必须以正确格式向终端提供数据。例如:

  • 某些终端需要转义引号

  • 在下列情况下,字符串参数应加引号:

    • 参数中,包含空格
    • 参数是一个列表参数,并包含逗号
    • 参数中包含转义字符
  • API 参数可以接受不同的数据类型,并且值(基于 JSON 规范)可能是错误的数据类型。

  • 使用 JSON 定义参数时,请为字符串 value 和字符串 key 加上引号。避免在 keyvalue 收尾加不必要的空白字符。

以下示例说明了一些参数的处理。

  • 要传递多个参数(每个参数都是一个字符串),不需要引号:
    在本例中,MySQL Shell 获取 2 个参数:参数 1simple,参数 2string
$ mysqlsh -- object function simple string
  • 如果希望将这两个字符串视为单个参数,则必须将它们括在引号("")中,如下所示。
    在此情况下,MySQL Shell 获取一个参数:参数 1simple string
$ mysqlsh -- object function "simple string"
  • 要使用包含反斜杠(\)等字符的参数,必须将字符串加引号("")。否则该字符将被忽略。例如:
    在这种情况下,MySQL Shell 获取 1 个参数:simpletstring,反斜杠(\)字符已被忽略。
$ mysqlsh -- object function simple\tstring
  • 为了确保反斜杠(\)字符可被传递到 MySQL Shell,请用引号("")将字符串引起来:
    在此情况下,MySQL Shell 获得 1 个参数:simple\\tstring
$ mysqlsh -- object function "simple\tstring"

使用命令行集成时,定义 JSON 数组有其自身的注意事项。例如,在 MySQL Shell 交互模式中,可以将 JSON 数组定义为:

["simple",123]

要在命令行集成中使用相同的数组则需要特定的引号。以下示例说明了如何正确为 JSON 数组使用引号:

  • 试图以与交互模式相同的方式传递 JSON 数组是行不通的:
    在此情况下,MySQL Shell 将获得 2 个参数:参数 1[simple,参数 2123]
$ mysqlsh -- object function ["simple", 123]
  • 在数组中不使用空格会有所帮助,但它仍然是一个无效的 JSON 数组:
    在此情况下,MySQL Shell 将获得 1 个参数:[simple,123]
$ mysqlsh -- object function ["simple",123]
  • 要创建有效的 JSON 数组,需在已加引号的字符串元素中添加转义引号(\"),例如:
    在此情况下,MySQL Shell 将获得 1 参数:["simple",123]
$ mysqlsh -- object function ["\"simple\"",123]

要使用包含 JSON 对象的 JSON 数组,需要以类似的方式加引号。例如,在 MySQL Shell 交互模式中,可以将包含 JSON 对象的 JSON 数组定义为

{"firstName":"John","lastName":"Smith"}

下面的示例说明了如何在命令行集成中正确传递上例中的数组。

  • 试图以与交互模式相同的方式传递 JSON 数组是行不通的:
    在此情况下,MySQL Shell 会获得 2 个参数:参数 1firstName:John,参数 2lastName:Smith
$ mysqlsh -- object function {"firstName":"John","lastName":"Smith"}
  • 对字符串数据使用转义引号会导致:
    在此情况下,MySQL Shell 会获得 2 个参数:参数 1"firstName":"John",参数 2"lastName":"Smith"
$ mysqlsh -- object function {"\"firstName\"":"\"John\"", "\"lastName\"":"\"Smith\""}
  • 要解决这个问题,需要在 JSON 对象最外层添加额外的引号(\"),来引起整个 JSON 对象:
    在这种情况下,MySQL Shell 会获取 1 个参数:{"firstName":"John","lastName":"Smith"}
$ mysqlsh -- object function "{"\"firstName\"":"\"John\"","\"lastName\"":"\"Smith\""}"

由于显示的困难以及不同平台中终端的行为方式可能不同的事实,因此支持以下格式。

  • 字符串参数
  • 列表参数
  • 字典参数
  • 附加的命名参数
5.8.2.2.1. 字符串参数

仅在以下情况下,才需要为字符串参数加引号:

  • 参数中包含空格
  • 参数中本身包含逗号并且用于列表参数(以避免拆分)
  • 参数中包含转义字符
  • 参数是一个数字、nulltruefalse,但它应该是一个字符串。在这些情况下,应该使用内部转义引号来引用该值。换句话说,如果字符串值为 "true",则应在 CLI 调用中将其定义为 ""true""
5.8.2.2.2. 列表(List)参数

除了 JSON 数组之外,列表参数的参数还可以以下列形式提供::

  • 逗号分隔的值列表
  • 单独的匿名参数

当处理列表参数时(按位置顺序),所有剩余的匿名参数都是列表的一部分。以下 MySQL Shell CLI 调用是等效的:

  • 使用逗号分隔的值列表:
$ mysqlsh root@localhost -- util dump-schemas sakila,employees
  • 使用连续的匿名参数:
$ mysqlsh root@localhost -- util dump-schemas sakila employees
  • 使用 JSON 数组:
$ mysqlsh root@localhost -- util dump-schemas ["\"sakila\"","\"employees\""]
5.8.2.2.3. 字典参数

字典是使用键值对创建的,字典参数中键(Key)的值也可以使用命名参数指定:

--key=value

以下 MySQL Shell CLI 调用说明了如何为 util.dumpInstance() 函数中的 options 参数定义 threadsosBucketName 键:

$ mysqlsh -- util dump-instance my-dump --threads=8 --osBucketName=my-bucket

列表键

可以通过以下方式定义字典中列表键的值:

  • 将值定义为 JSON 数组。
  • 将值定义为逗号分隔的值列表。
  • 重复定义键的值。

例如,在以下调用中,传递给 util.dumpInstance() 操作的 exceptSchemas 键的定义是等效的:

  • 使用 JSON 数组:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=["\"sakila\"","\"employees\""]
  • 使用逗号分隔的值列表:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=sakila,employees
  • 重复定义多个 --excludeSchemas 键:
$ mysqlsh root@localhost -- util dump-instance --outputUrl="my-dump" --excludeSchemas=sakila --excludeSchemas=employees

字典键

支持嵌套字典,但有以下限制:

  • 仅支持一层嵌套。
  • 不支持内部预定义键的验证。
  • 不支持内部预期数据类型的验证。

为嵌套字典中的键定义值的语法如下:

--key=innerKey=value

例如,定义 decodeColumns 键,并将其传递给 util.importTable() 操作:

$ mysqlsh -- util import-table --decodeColumns=myColumn=1
5.8.2.2.4. 额外的俱名参数

如上一节所示,字典参数通过使用 --key=value 语法的命名参数来支持。还有另一种情况,参数必须指定为 命名参数(在列表参数之后定义的参数)。要提供属于列表参数的参数,最便捷方法是使用匿名参数,例如列表参数中的示例所示:

$ mysqlsh root@localhost -- util dump-schemas sakila employees

但是,此示例缺少 outputUrl 参数的参数,该参数对于 util.dumpSchemas() 操作是必需的。由于所有剩余的匿名参数都包含在 schema 列表中,因此无法将outputUrl 指定为匿名参数。例如,以下内容将不起作用:

$ mysqlsh root@localhost -- util dump-schemas sakila employees path/to/dump

在此调用中,路径 path/to/dump 将被解释为 schema 列表中的一项。因此,从命令行调用函数时,在列表参数之后定义的任何参数都必须指定为 命名参数。例如:

$ mysqlsh root@localhost -- util dump-schemas sakila employees --outputUrl=path/to/dump

5.8.2.3. 数据类型处理

一般情况下,参数的数据类型按优先顺序使用以下标准来确定:

  • 目标参数的预期数据类型。
  • 基于 JSON 规范的值的数据类型。
  • 用户指定的数据类型。

最后一种情况比较复杂(也比较少见),只适用于命名参数。例如,假设你有一个 MySQL Shell 插件函数,如:

def set_object_attributes(variables)

variables 是一个字典,没有预定义的值集,因此它接受任何键,也就接受任何数据类型的值。要将名为 streetNumber 的字符串属性设置为字符串值 123,请执行以下操作

$ mysqlsh -- plugin set-object-attributes --streetNumber=123

由于没有预期的数据类型,因此根据 JSON 规范,值 123 被解释为数值,但我们希望将其存储为字符串,而不是数字。

:::alert-info
【Note】
目前不存在这样的 API 函数,除非用户创建如上所述的插件。
:::

5.8.2.3.1. 用户数据类型

为了避免 MySQL Shell 尝试猜测输入数据类型的问题,命令行集成支持通过使用以下语法指定命名参数来强制使用特定数据类型:

--key:<type>=value

其中, type 为:

  • str
  • int
  • uint
  • float
  • bool
  • list
  • dict
  • json

如指定类型为字符串:

$ mysqlsh -- plugin set-object-attributes --streetNumber:str=1234

:::alert-info
【Important】
任何命名参数都可以使用这种格式,但在参数没有预期数据类型时才需要使用。如果参数有预期的数据类型,而你指定了不同的数据类型,则会出错。
:::

5.8.2.3.2. 数据类型解析

当未指定数据类型时,MySQL Shell 会尝试使用以下逻辑进行数据类型解析。该逻辑基于 JSON 规范,但有一些 MySQL Shell 特有的补充和限制:

  • Strings

    • 支持双引号和单引号字符串。
    • 支持十六进制,如 \xNN,其中 NN 是十六进制数字。这用于以十六进制格式表示 ASCII 字符。
    • 支持垂直制表符转义字符
  • 还可以定义以下文字

    • undefined:将值定义为 undefinedCLI 中并不真正需要,因此不鼓励使用)。
    • true/false:创建一个 bool
    • null:定义一个 null 空值

JSON 规范以及上述规则未涵盖的任何值都会被解释为普通字符串。

5.8.2.4. 命令行帮助

使用 --help (-h) CLI 参数从命令行集成调用命令时,可以访问 MySQL Shell 联机帮助。在全局、对象和命令级别支持帮助。

:::alert-info
【Note】
内置帮助 CLI 参数不会映射到任何 API 参数,CLI 中的所有对象和命令都支持该参数。
:::

命令和参数的描述取自目标 API 函数的现有文档。

5.8.2.4.1. 全局 CLI 帮助

要检索可用于 CLI 调用的全局对象列表,请使用以下语法:

$ mysqlsh -- --help

在本例中,-- 启动了命令行集成部分。之后单独使用 --help-h 选项,会列出该接口中可用的全局对象。

5.8.2.4.2. 对象帮助

要从命令行集成访问对象帮助,请使用以下语法:

$ mysqlsh -- object --help

其中 object 是需要帮助的对象,例如 dba 全局对象。此调用显示:

  • 对象的简要描述。
  • 可用命令的列表及其简短描述。

要检索嵌套对象的帮助,请在 --help 参数之前提供完整的对象列表。例如,要获取有关 shell.options 函数的帮助,请发出:

$ mysqlsh -- shell options --help
5.8.2.4.3. 命令帮助

要显示命令行集成中命令的帮助,请使用以下语法:

$ mysqlsh -- object command --help

此调用显示有关 command 的详细信息,包括:

  • 该命令的作用的简要描述。
  • 调用命令的签名。
  • 匿名参数列表以及每个参数的简要描述。
  • 命名参数的列表、它们的预期数据类型以及解释每个参数用途的简短描述。

对于嵌套对象中的命令,例如,应在命令前提供整个对象列表:

$ mysqlsh shell options set-persist --help

对于期望使用特定数据类型的参数,参数会被列为

--name=type Brief description of the parameter.

类型信息表示参数的预期数据类型,例如:strintuintboollistfloatdict

例如 dump-schemas 参数的 consistency key

$ mysqlsh -- util dump-schemas --help ... --consistent=<bool> Enable or disable consistent data dumps. Default: true. ...

对于支持不同数据类型的参数,参数会被列为

--name[:type]=value Brief description of the parameter.

例如,util.importTable() 操作的 columns 选项。

$ mysqlsh -- util import-table --help ... --columns[:<type>]=<value> Array of strings and/or integers (default: empty array) - This... ...

5.8.2.5. 对 MySQL Shell 插件的支持

要在命令行集成中使用 MySQL Shell 插件,必须为 CLI 支持明确定义函数。当为命令行集成启用 MySQL Shell 插件中定义的对象时,只有启用的特定函数可用于 CLI 调用。从 MySQL Shell ≥ 8.0.24,当你向对象添加函数成员时,它们支持 cli 布尔值选项。当 cli 设置为 true 时,函数可通过命令行集成使用。cli 选项的默认值为 false,因此除非特别启用,否则不能通过命令行集成使用函数。任何带有启用了 cli 选项的函数的对象都会导致其父对象也可在命令行集成中使用。

要通过命令行集成使函数可用,请在添加扩展对象成员时将 cli 选项设置为 true。例如:

shell.addExtensionObjectMember(object, "exampleFunction", exampleFunction, { brief:"Retrieves brief information", details: ["Retrieves detailed information"], cli: true, parameters: [ { name: "param_a", type: "string", brief: "param_a brief" } ] });

然后,可以使用命令行集成中的 exampleFunction() 函数,如下所示:

mysqlsh -- customObj exampleFunction 1

如果使用 MySQL Shell < 8.0.24 版本添加了扩展对象成员,并且想要将其与命令行集成一起使用,则必须启用 cli 选项。使用此处所示的 addExtensionObjectMember 方法再次添加对象成员,这次启用 cli 选项。

5.9. JSON 集成

MySQL Shell 8.0.27 开始,可以激活 JSON shell 模式,以帮助将 MySQL Shell 与其他可以使用其功能的应用程序集成。在此模式下,MySQL Shell 接受 JSON 文档格式的命令。

要激活 JSON shell 模式,请定义 MYSQLSH_JSON_SHELL 环境变量。然后可以使用以下命令:

  • {"execute":json-string}
    在活动的 MySQL Shell 模式(JavaScriptPythonSQL)中执行给定代码。代码作为一个完整的单元执行,如果不完整则返回错误。

  • {"command":json-string}
    执行给定的 MySQL Shell 命令(请参阅 MySQL Shell 命令)。

  • {"complete":{"data":json-string[, "offset": uint}}}
    根据给定数据和当前 MySQL Shell 上下文确定自动补全选项。


免责声明:

1、本站资源由自动抓取工具收集整理于网络。

2、本站不承担由于内容的合法性及真实性所引起的一切争议和法律责任。

3、电子书、小说等仅供网友预览使用,书籍版权归作者或出版社所有。

4、如作者、出版社认为资源涉及侵权,请联系本站,本站将在收到通知书后尽快删除您认为侵权的作品。

5、如果您喜欢本资源,请您支持作者,购买正版内容。

6、资源失效,请下方留言,欢迎分享资源链接

文章评论

0条评论