跳转到主要内容

根据特定架构转换数据集

项目描述

ckanext-transmute

此扩展可以帮助验证并根据特定架构转换数据集。

与transmute一起工作

ckanext-transmute提供了一个名为tsm_transmute的操作,它帮助我们使用提供的转换方案转换数据。此操作不会更改原始数据,而是创建一个新的数据字典。有两个必填参数 - dataschema。其中data是一个数据字典,您有schema则帮助您验证/更改其中的数据。

示例:我们有一个数据字典

{
            "title": "Test-dataset",
            "email": "test@test.ua",
            "metadata_created": "",
            "metadata_modified": "",
            "metadata_reviewed": "",
            "resources": [
                {
                    "title": "test-res",
                    "extension": "xml",
                    "web": "https://stackoverflow.com/",
                    "sub-resources": [
                        {
                            "title": "sub-res",
                            "extension": "csv",
                            "extra": "should-be-removed",
                        }
                    ],
                },
                {
                    "title": "test-res2",
                    "extension": "csv",
                    "web": "https://stackoverflow.com/",
                },
            ],
        }

我们想要达到这个效果

{
            "name": "test-dataset",
            "email": "test@test.ua",
            "metadata_created": datetime.datetime(2022, 2, 3, 15, 54, 26, 359453),
            "metadata_modified": datetime.datetime(2022, 2, 3, 15, 54, 26, 359453),
            "metadata_reviewed": datetime.datetime(2022, 2, 3, 15, 54, 26, 359453),
            "attachments": [
                {
                    "name": "test-res",
                    "format": "XML",
                    "url": "https://stackoverflow.com/",
                    "sub-resources": [{"name": "SUB-RES", "format": "CSV"}],
                },
                {
                    "name": "test-res2",
                    "format": "CSV",
                    "url": "https://stackoverflow.com/",
                },
            ],
        }

那么,我们的架构必须类似于这样

{
        "root": "Dataset",
        "types": {
            "Dataset": {
                "fields": {
                    "title": {
                        "validators": [
                            "tsm_string_only",
                            "tsm_to_lowercase",
                            "tsm_name_validator",
                        ],
                        "map": "name",
                    },
                    "resources": {
                        "type": "Resource",
                        "multiple": True,
                        "map": "attachments",
                    },
                    "metadata_created": {
                        "validators": ["tsm_isodate"],
                        "default": "2022-02-03T15:54:26.359453",
                    },
                    "metadata_modified": {
                        "validators": ["tsm_isodate"],
                        "default_from": "metadata_created",
                    },
                    "metadata_reviewed": {
                        "validators": ["tsm_isodate"],
                        "replace_from": "metadata_modified",
                    },
                }
            },
            "Resource": {
                "fields": {
                    "title": {
                        "validators": ["tsm_string_only"],
                        "map": "name",
                    },
                    "extension": {
                        "validators": ["tsm_string_only", "tsm_to_uppercase"],
                        "map": "format",
                    },
                    "web": {
                        "validators": ["tsm_string_only"],
                        "map": "url",
                    },
                    "sub-resources": {
                        "type": "Sub-Resource",
                        "multiple": True,
                    },
                },
            },
            "Sub-Resource": {
                "fields": {
                    "title": {
                        "validators": ["tsm_string_only", "tsm_to_uppercase"],
                        "map": "name",
                    },
                    "extension": {
                        "validators": ["tsm_string_only", "tsm_to_uppercase"],
                        "map": "format",
                    },
                    "extra": {
                        "remove": True,
                    },
                }
            },
        },
    }

这是一个具有嵌套类型的架构示例。root字段是必填的,它必须包含主类型名称,从该名称开始架构。正如您所看到的,Dataset类型包含Resource类型,而Resource类型又包含Sub-Resource

转换器

有几个默认的转换器您可以在架构中使用。当然,您可以使用ITransmute接口定义自定义转换器。

  • tsm_name_validator - 对 CKAN 默认的 name_validator 验证器进行包装
  • tsm_to_lowercase - 将字符串值转换为小写
  • tsm_to_uppercase - 将字符串值转换为大写
  • tsm_string_only - 验证 field.value 是否为字符串
  • tsm_isodate - 验证日期时间字符串。将类似 ISO 的字符串转换为日期对象
  • tsm_to_string - 将 field.value 转换为 str
  • tsm_get_nested - 允许您从嵌套结构中获取值。示例
data = "title_translated": [
    {"nested_field": {"en": "en title", "ar": "العنوان ar"}},
]

schema = ...
    "title": {
        "replace_from": "title_translated",
        "validators": [
            ["tsm_get_nested", 0, "nested_field", "en"],
            "tsm_to_uppercase",
        ],
    },
    ...

这将从 title_translated 字段获取 title 字段的值。因为 title_translated 是一个包含嵌套对象的数组,所以我们使用 tsm_get_nested 转换器来实现从它获取值。

  • tsm_trim_string - 剪切字符串。例如,将 hello world 剪切为 hello
data = {"field_name": "hello world}

schema = ...
    "field_name": {
        "validators": [
            ["tsm_trim_string", 5]
        ],
    },
    ...
  • tsm_concat - 剪切字符串。使用 $self 指向字段值。示例
data = {"id": "dataset-1}

schema = ...
    "package_url": {
        "replace_from": "id",
        "validators": [
            [
                "tsm_concat",
                "https://site.url/dataset/",
                "$self",
            ]
        ],
    },
    ...
  • tsm_unique_only - 从列表中保留唯一值。仅适用于列表。

默认转换器必须接收至少一个必填参数 - field 对象。字段包含一些属性:field_namevaluetype

可以向验证器提供更多参数,如 tsm_get_nested。为此,使用嵌套数组,第一个元素是转换器,其余的是对其的参数。

关键字

  1. map_to (str) - 改变结果字典中的 field.name
  2. validators (list[str]) - 将应用于 field.value 的转换器列表。转换器可以是 stringlist,其中第一个元素必须是转换器名称,其余是任意值。示例
    ...
    "validators": [
        ["tsm_get_nested", "nested_field", "en"],
        "tsm_to_uppercase",
    ,
    ...
    
    有两个转换器:tsm_get_nestedtsm_to_uppercase
  3. multiple (bool, 默认: False) - 如果字段可以有多个项目,例如数据集中 resources 字段的标记为 multiple,以连续转换所有项目。
    ...
    "resources": {
        "type": "Resource",
        "multiple": True
    },
    ...
    
  4. remove (bool, 默认: False) - 如果为 True,则从结果字典中删除字段。
  5. default (Any) - 如果原始字段值评估为 False,则将使用的默认值。
  6. default_from (str | list) - 与 default 类似,但接受一个来自同级字段的 field.name,我们希望从中获取其值。同级字段位于同一 type 中。当前实现不允许指向来自其他 types 的字段。可以接受一个表示 field.name 的字符串,或一个字符串数组,以使用多个字段。有关详细信息,请参阅 inherit_mode 关键字。
    ...
    "metadata_modified": {
        "validators": ["tsm_isodate"],
        "default_from": "metadata_created",
    },
    ...
    
  7. replace_from (str| list) - 与 default_from 类似,但在值为空或不是时替换原始值。
  8. inherit_mode (str, 默认: combine) - 定义 default_fromreplace_from 的模式。默认情况下,我们正在组合所有字段的值,但我们可以只使用第一个非假值,如果字段可能为空。
  9. value (Any) - 将用于字段的值。此关键字具有最高优先级。可用于创建具有任意值的字段。
  10. update (bool, 默认: False) - 如果原始值是可变的(数组、对象) - 您可以更新它。您只能更新相同类型的字段值。

安装

要安装 ckanext-transmute

  1. 激活您的 CKAN 虚拟环境,例如

    . /usr/lib/ckan/default/bin/activate

  2. 克隆源并在虚拟环境中安装它

    git clone https://github.com/mutantsan/ckanext-transmute.git cd ckanext-transmute pip install -e . pip install -r requirements.txt

  3. transmute 添加到您的 CKAN 配置文件中的 ckan.plugins 设置(默认情况下,配置文件位于 /etc/ckan/default/ckan.ini)。

  4. 重启 CKAN。例如,如果您在 Ubuntu 上使用 Apache 部署了 CKAN

    sudo service apache2 reload

开发者安装

为了开发安装 ckanext-transmute,请激活您的 CKAN 虚拟环境,并执行以下操作:

git clone https://github.com/mutantsan/ckanext-transmute.git
cd ckanext-transmute
python setup.py develop
pip install -r dev-requirements.txt

测试

我已经使用 TDD 编写了这个扩展,所以如果您更改了某些内容,请确保所有测试都是有效的。要运行测试,请执行以下操作:

pytest --ckan-ini=test.ini

许可证

AGPL

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源分布

ckanext-transmute-1.6.0.tar.gz (33.1 kB 查看哈希值)

上传时间

构建分布

ckanext_transmute-1.6.0-py3-none-any.whl (34.0 kB 查看哈希值)

上传时间 Python 3

支持者