Skip to content

"versioning": True, KeyError: 'custom_DOMAIN_KEY_versions' #1423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yanbing2020 opened this issue Nov 26, 2020 · 0 comments
Closed

"versioning": True, KeyError: 'custom_DOMAIN_KEY_versions' #1423

yanbing2020 opened this issue Nov 26, 2020 · 0 comments

Comments

@yanbing2020
Copy link
Contributor

Hi,

Recently, I tried using the eve to design a CMDB system, a situation happened.
In Schema Definition,I'd like to use custom datasource and { "versioning": True, } at the same time, when i PATCH a document, the behind Traceback happened.

Some part of my Schema Definition

"datasource": {
        "source": "resource_APP",
    },
"versioning": True,

Expected Behavior

PATCH document and versioned document will inserted to the next two mongo collections separately.

# domain_key = 'APP'
resource_APP
resource_APP_versions

example:

some code in app.py:

from micro_ops.event_hook import (
    init_register,
)

def create_app(config_object="micro_ops.settings"):
    """
    :param config_object: The configuration object to use.
    """
    app = Eve(settings="eve_settings.py")

    # init register resource
    with app.app_context():
        init_register()

    app.on_inserted_resource += inserted_resource
    app.on_updated_resource += updated_resource

    app.add_url_rule(
        "/graphql",
        view_func=GraphQLView.as_view("graphql", schema=schema, graphiql=True),
    )

    app.config.from_object(config_object)
    register_extensions(app)
    register_blueprints(app)
    register_errorhandlers(app)
    register_shellcontext(app)
    register_commands(app)
    configure_logger(app)
    return app

event_hook.py:

# -*- coding: utf-8 -*-
"""Helper utilities and decorators."""

import copy

from flask import current_app

# init register resource definition
def init_register():
    app = current_app._get_current_object()
    db_client = app.data.pymongo().db
    cursor = db_client["resource_definition"].find()
    for item in cursor:
        # print(item)
        try:
            register_item(item)
        except BaseException as identifier:
            print(identifier)
        finally:
            pass
    pass


# register an item by domain_key
def register_item(item):
    """
    register an domain_key
    """
    resource_definition = copy.deepcopy(DEFINITION_TEMPLATE)
    definition_data = item
    resource_attr_list = definition_data["object_schema"]
    if len(resource_attr_list) == 0:
        return
    schema = generate_schema(resource_attr_list)

    domain_key = definition_data["object_id"]
    resource_definition["schema"] = schema

    resource_definition["item_title"] = domain_key
    resource_definition["url"] = domain_key
    resource_definition["datasource"]["source"] = "resource_{}".format(domain_key)

    current_app.register_resource(domain_key, resource_definition)
    print("object: {} is modified and now is registered!".format(domain_key))


def generate_schema(resource_attr_list):
    # init an empty schema
    schema = {}
    for resource_attr in resource_attr_list:
        field_type = resource_attr["type"]
        field_map = copy.deepcopy(FIELD_MAP[field_type])
        if field_type == "string":
            field_map["required"] = resource_attr["required"]
            field_map["unique"] = resource_attr["unique"]

        filed_key = resource_attr["id"]
        schema[filed_key] = field_map

    return schema


FIELD_MAP = {
    "string": {
        "type": "string",
        "minlength": 1,
        "maxlength": 15,
        "required": False,
        "unique": False,
    },
}

SCHEMA_TEMPLATE = {
    "object_id": {
        "type": "string",
        "minlength": 1,
        "maxlength": 32,
        "regex": "^[A-Z]+$",
        "required": True,
        "unique": True,
    },
    "name": {
        "type": "string",
        "minlength": 1,
        "maxlength": 15,
        "required": True,
    },
    # An embedded 'strongly-typed' dictionary.
    "category": {
        "type": "dict",
        "schema": {"_id": {"type": "objectid"}, "_version": {"type": "integer"}},
        "data_relation": {
            "resource": "category",
            "field": "_id",
            "embeddable": True,
            "version": False,
        },
    },
}

DEFINITION_TEMPLATE = {
    "datasource": {
        "source": "",
    },
    "additional_lookup": {"url": r'regex("[\w]+")', "field": "name"},
    "cache_control": "max-age=10,must-revalidate",
    "cache_expires": 10,
    "schema": SCHEMA_TEMPLATE,
    "soft_delete": True,
    "versioning": True,
}

Actual Behavior

[2020-11-25 17:46:42,772] ERROR in patch: 'resource_APP_versions'
Traceback (most recent call last):
  File "/Users/abin/code/Lipotes/micro-api/.env3.6/lib/python3.6/site-packages/eve/methods/patch.py", line 239, in patch_internal
    insert_versioning_documents(resource, updated)
  File "/Users/abin/code/Lipotes/micro-api/.env3.6/lib/python3.6/site-packages/eve/versioning.py", line 159, in insert_versioning_documents
    app.data.insert(versionable_resource_name, versioned_documents)
  File "/Users/abin/code/Lipotes/micro-api/.env3.6/lib/python3.6/site-packages/eve/io/mongo/mongo.py", line 460, in insert
    datasource, _, _, _ = self._datasource_ex(resource)
  File "/Users/abin/code/Lipotes/micro-api/.env3.6/lib/python3.6/site-packages/eve/io/base.py", line 424, in _datasource_ex
    datasource, filter_, projection_, sort_ = self.datasource(resource)
  File "/Users/abin/code/Lipotes/micro-api/.env3.6/lib/python3.6/site-packages/eve/io/base.py", line 359, in datasource
    dsource = config.SOURCES[resource]
KeyError: 'resource_APP_versions'

In debugging mode, I have tried the next code, and it will successfully get dsource. and following,the versioned document will inserted to a collection named 'resource_APP_versions', which is the Expected Behavior.

dsource = config.SOURCES['APP_versions']

thanks!

Environment

  • Python version:3.6.6
  • Eve version:1.1.4
  • MacOS 10.15.7
yanbing2020 added a commit to LipotesOps/eve that referenced this issue Nov 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant