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
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
Expected Behavior
PATCH document and versioned document will inserted to the next two mongo collections separately.
example:
some code in app.py:
event_hook.py:
Actual Behavior
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.
thanks!
Environment