在官方 MySQL 应用程序中有点独特,MySQL Shell 提供(简单的)JSON 输出。在 MySQL shell 提示符下,键入以下内容将获得 JavaScript 对象数组的结果(每行一个):
\option resultFormat json/array
\use information_schema
SELECT table_catalog, table_schema, table_name, engine, create_time, table_collation
FROM tables
WHERE table_schema='INFORMATION_SCHEMA' AND table_name LIKE 'T%';
然后将其传递给寻呼机以在屏幕上显示。如何将输出重定向或以其他方式保存到文件(例如名为 results.json)?
(注意:查询可以是任何东西。以上内容是作为一个简单但不重要的测试用例提供的,应该可以针对任何 MySQL 安装运行。)
由于 MySQL Shell 可在各种平台上使用,因此首选平台无关解决方案,但特定平台的解决方案也很受关注。
简单的解决方案
据我所知,有两种简单的方法。一种是从非交互模式下的登录 shell 命令行,另一种是(ab)使用 MySQL Shell 的
\pager
命令。登录外壳
登录 shell 方式是捕获任何命令输出以及
mysqlsh
运行查询的特定参数的方法。对于 Unix shell:对于 PowerShell,变量设置不同(即使用
sv sql "..."
),但其余部分相同。\pager 诡计
旧的 mysql 客户端有一个可以将输出发送到文件的
tee
命令。虽然 MySQL Shell 没有类似的命令,\pager
但可以设置为(登录 shell)命令,将结果输出到文件。如果您还想查看结果,请使用tee
系统具有的任何命令。如果您不想看到结果,请使用不产生任何输出的登录 shell 命令,例如
\pager cat >results.json
or\pager type >results.json
。请注意,每个查询结果都将替换前一个查询结果(有点诡计,您可能会创建一个命令来选择每次运行时都不存在的文件名)。
另请注意,输出将在末尾包含结果摘要(“ <N>行中的集合(<时间>秒)”)。如果你不想要这个,要么从文件中删除它,要么通过一个命令在输出到文件之前将结果删除(例如
grep -E -v '^[0-9]+ rows in set \([.0-9]+ sec\)$' | tee results.json
,或Select -SkipLast 1 | Tee-Object results.json
;参见“尾的相反:除了最后 n 行之外的所有行”更多 Unix 选项)。如果您想查看分页结果,您仍然可以通过寻呼机传送结果。例如:
复杂的解决方案
Python
可以交互地使用 Python,但只能使用适当定义的助手。由于此解决方案依赖于编码,因此它可能与 DBA.SE 无关,更适合 SO。但是,为此解决方案创建有关 SO 的相关问题的替代方法接近交叉发布并分裂答案,因此此处提供了解决方案。
Result
在编程模式(JS或Python)中,查询结果是ClassicResult
对象。MySQL Shell 在显示它们时会对其进行格式化,但结果本身没有格式。这意味着在任何编程模式下,结果都必须在输出之前以编程方式格式化。Python 引擎有
open
,并且该json
模块可用。在这两者之间,可以定义合适的函数来将结果格式化为 JSON 并将它们输出到文件中。json.JSONEncoder
不支持Result
andClassicResult
,因此要么需要定义合适的 JSONEncoder,要么需要将它们转换为内置类型,任何不是内置类型的字段(例如Date
列)也一样。后者可以相当简洁地完成。首先,领域。判断是否
json
可以对字段进行编码的一个简单方法是尝试它并通过将值转换为字符串来处理失败。此外,该字段将按名称从使用的行中获取get_field
。转换为内置类型非常简单:必须获取结果,然后列表和字典推导将行数据组装成内置类型,使用上述
row_field()
方法来获取和转换字段。json.dump()
将支持的对象转换为 JSON 并输出到给定的文件对象。要将所有内容联系在一起,这里有一个函数可以转换结果、打开文件并将它们传递给json.dump()
.上述功能可以添加到从 8.0.17 版本开始的插件中。在您平台上的“插件”目录中,将上述函数(和一条
import json
语句)放入插件文件夹(例如“dump_json/init.py”)中的初始化脚本中,以及以下内容以创建扩展并添加文件输出函数(改编自示例插件):dump_json
然后可以通过ext
MySQL Shell 中的全局访问该函数:如果使用早于 8.0.17 的版本,请改为使用辅助函数创建 Python 模块(创建扩展
ext
并添加dump_json
到它的代码应该省略),以及import
来自 MySQL shell 的模块。死胡同
在交互式 shell 中,
INTO OUTFILE
由服务器处理,因此没有机会被 MySQL Shell 格式化。更一般地说,SQL 是在服务器端解释的,没有办法指导客户端将结果保存到文件中,因此 MySQL Shell 中的交互式 SQL 模式本身无法提供解决方案。JavaScript 没有访问文件的标准方式(内置的或来自库的)。MySQL JS API提供了一些自己的方法,例如通过
os
和util
的各种文件 I/O 方法读取文本文件,但不提供通用文件输出。util
在两个方面未达标:虽然它有一些文件输出方法,但它们只能转储数据库和表(不是任意查询结果)并且只能以标准转储格式转储。(不过,一种普遍感兴趣的方法是util.importJSON
,它支持将 JSON 文件导入文档存储。)此外,JavaScript 模式似乎没有标准 JSON 对象来生成 JSON 输出。