sqlite-transform 作者 simonw

星标

README 源代码

sqlite-transform

No longer maintained PyPI Changelog Tests License

用于在 SQLite 数据库中对列运行转换的工具。

⚠️此工具不再维护

我向 sqlite-utils 添加了一个新工具,名为 sqlite-utils convert,它提供了此处最初提供的功能的超集。sqlite-transform 不再维护,我建议改为使用 sqlite-utils convert

如何安装

pip install sqlite-transform

parsedate 和 parsedatetime

这些子命令将通过 dateutils.parser.parse() 处理指定列中的所有值,并将其替换为结果,格式化为 ISO 时间戳或 ISO 日期。

例如,如果数据库中的某行有一个 opened 列,其中包含 10/10/2019 08:10:00 PM,运行以下命令

sqlite-transform parsedatetime my.db mytable opened

将导致该值被替换为 2019-10-10T20:10:00

在这里使用 parsedate 子命令将得到 2019-10-10

对于像 03/04/05 这样的模糊日期,这些命令都默认假定为美国式 mm/dd/yy 格式。你可以传递 --dayfirst 来指定假定日期优先,或传递 --yearfirst 来指定年份优先。

jsonsplit

jsonsplit 子命令处理包含逗号分隔列表的列,例如一个 tags 列包含 "trees,park,dogs" 这样的记录,并将其转换为 JSON 数组 ["trees", "park", "dogs"]

这对于利用 Datasette 的按 JSON 数组分面功能非常有用。

sqlite-transform jsonsplit my.db mytable tags

它默认按逗号分割,但你可以使用 --delimiter 选项指定不同的分隔符,例如

sqlite-transform jsonsplit \
    my.db mytable tags --delimiter ';'

数组中的值将被视为字符串,因此包含 123,552,775 的列将被转换为 JSON 数组 ["123", "552", "775"]

你可以使用 --type int--type float 为这些值指定不同的类型,例如

sqlite-transform jsonsplit \
    my.db mytable tags --type int

这将导致该列被转换为 [123, 552, 775]

lambda 用于执行你自己的代码

lambda 子命令允许你指定将针对该列执行的 Python 代码。

以下是如何将列转换为大写

sqlite-transform lambda my.db mytable mycolumn --code='str(value).upper()'

你提供的代码将被编译成一个接受 value 作为单个参数的函数。你可以将函数体分成多行,只要最后一行是 return 语句即可

sqlite-transform lambda my.db mytable mycolumn --code='value = str(value)
return value.upper()'

你还可以使用一个或多个 --import 选项指定应导入并提供给你的代码使用的 Python 模块

sqlite-transform lambda my.db mytable mycolumn \
    --code='"\n".join(textwrap.wrap(value, 10))' \
    --import=textwrap

--dry-run 选项将输出对前十行转换的预览,而不会修改数据库。

将结果保存到单独的列

每个命令都接受可选的 --output--output-type 选项。这些选项可用于将转换结果保存到单独的列中,如果该列尚不存在,则会创建它。

要将 jsonsplit 的结果保存到名为 json_tags 的新列中,请使用以下命令

sqlite-transform jsonsplit my.db mytable tags \
  --output json_tags

创建的列类型默认为 text,但可以使用 --output-type 指定不同的列类型。此示例将创建一个名为 float_id 的新浮点列,其中包含每个项目的 ID 副本并增加 0.5

sqlite-transform lambda my.db mytable id \
  --code 'float(value) + 0.5' \
  --output float_id \
  --output-type float

你可以在操作结束时通过添加 --drop 来删除原始列。

将列分割成多个列

有时你可能希望将单个列转换为多个派生列。例如,你可能有一个包含 latitude,longitude 值的 location 列,希望将其拆分为单独的 latitudelongitude 列。

你可以使用 sqlite-transform lambda--multi 选项实现此目的。此选项要求你的 --code 函数返回一个 Python 字典:将为该字典中的每个键创建并填充新列。

对于 latitude,longitude 示例,你可以使用以下命令

sqlite-transform lambda demo.db places location \
  --code 'return {
    "latitude": float(value.split(",")[0]),
    "longitude": float(value.split(",")[1]),
  }' --multi

创建新列时将考虑返回值的类型。在此示例中,生成的数据库模式将如下所示

CREATE TABLE [places] (
    [location] TEXT,
    [latitude] FLOAT,
    [longitude] FLOAT
);

代码函数也可以返回 None,在这种情况下,其输出将被忽略。

你可以在操作结束时通过添加 --drop 来删除原始列。

禁用进度条

默认情况下,每个命令都会显示一个进度条。传递 -s--silent 可以隐藏进度条。