从json模式动态创建mongoengine类



我正在寻找一种方法来获取json模式,并在运行时动态创建mongoengine类。

例如:写在下面的mongoengine类

class user(Document):
     _id  = StringField(required=False) # mongodb id
     name = StringField(required=True)  # user name
     email= StringField(required=False,regex="^[a-zA-Z0-9]*@mydomain.com$")  # user email

将与从该模式生成的运行时动态生成的类相同

{
"type":"object",
"properties":{
    "_id"      : {"type":"string"},
    "name"     : {"type":"string"},
    "email"    : {"pattern":"^[a-zA-Z0-9]*@mydomain.com$"}
    }
}

有什么建议吗?

您可以动态创建python类,如下所示:

user_properties = { 
   '_id': StringField(required=False), # mongodb id
   'name': StringField(required=True), # user name
   'email': StringField(required=False,regex="^[a-zA-Z0-9]*@mydomain.com$"),  # user email
}
User = type("User", (Document, ), user_properties)

剩下的是来自dict的唯一转换器;你的模式";其将被转换为dict user_properties

此外,以下是我对类似问题";如何从已经存在的集合生成mongoengine文档的模型";这也会有所帮助。

jinja模板引擎具有可用于创建mongo类模板的功能,该模板根据每个属性的类型在类定义中填充属性模式。然后,我们使用一个渲染该模板的简单中间脚本动态生成所需的Python类。以下是说明这一概念的示例。我们从以下项目结构开始,它有一个名为Templates的示例父文件夹和三个文件:

Templates
    - mongo_sample.schema.json
    - mongoclass_template.jinja
    - auto_mongo_class.py

让我们探索一下这些文件:

1.mongo_sample.schema.json

这是MongoDB模式文档。一致的模式有助于以后创建标准的Jinja模板:

{
  "type":"object",
  "required": ["name"],
  "properties":{
      "_id"      : {"type":"string"},
      "name"     : {"type":"string"},
      "email"    : {"pattern":"^[a-zA-Z0-9]*@mydomain.com$"}
    }
}

2.mongbreakers_template.jinja:

这是Mongo类的Jinja模板,它最终将用于呈现所需的Python Mongo类。它使用了Jinja模板语言。这是模板设计器文档的参考资料。在这里,我们所做的就是创建一个涵盖所有";类型";情况以及诸如";"必需";以及";regex";。请注意,一致的模式很重要:

from mongoengine import DynamicDocument, StringField, IntField
class Student(DynamicDocument):       
    {%- for prop, val in properties.items() %} 
    {%- if prop in required -%}
    {% set req = True %}
    {% else %}    
    {% set req = False %}
    {%- endif -%}
    {%- if val.pattern is defined -%}
    {% set patt = val.pattern %}    
    {% else %}
    {% set patt = None %} 
    {%- endif -%}  
    {%- if val.type == "string" -%}
    {{prop}} = StringField(required={{req}}, regex={{patt}})
    {%- elif val.type == "int" -%}
    {{prop}} = IntField(required={{req}})        
    {%- else -%} 
    {{prop}} = StringField(required={{req}}, regex="{{patt}}")       
    {%- endif -%}
    {%- endfor %}
    

3.auto_mongo_class.py:

这个Python脚本解析上面的JSON模式以获得属性对象,将必要的变量传递给模板render()方法,该方法将在渲染模板时使用,并最终写入一个名为models.py的Python文件,该文件是最后一个Mongo类:

import json
from jinja2 import Template
with open(r"mongo_sample.schema.json", "r") as schema_json:
    schema_tree = json.load(schema_json)
properties = schema_tree["properties"]
required = schema_tree["required"]
template = Template(open(r"mongoclass_template.jinja").read()).render(properties=properties, 
    required=required)
with open("models.py", 'w') as file_:
    file_.write(template)

现在,让我们运行这个脚本:

python auto_mongo_class.py

一个名为models.py的新Python脚本将出现在项目文件夹中,其中包含以下内容:

from mongoengine import DynamicDocument, StringField, IntField
class Student(DynamicDocument):    
    
    _id = StringField(required=False, regex=None)
    
    name = StringField(required=True, regex=None)    
        
    email = StringField(required=False, regex="^[a-zA-Z0-9]*@mydomain.com$")

最新更新