从json schema动态创建mongoengine类

时间:2015-11-25 15:14:22

标签: python json mongoengine jsonschema

我正在寻找一种方法来获取我的json架构并在运行时动态创建一个mongoengine类。

例如: 下面写的mongoengine课程

if (
navigator.userAgent.indexOf('Safari') != -1 
&& 
navigator.userAgent.indexOf('Chrome') == -1
)

与从此模式生成的运行时类中动态生成的

相同
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

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

您可以动态创建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

此外,这里的my answer类似于类似的问题“ How to generate a model for a mongoengine Document from an already existing collection”,它也可以提供帮助。

答案 1 :(得分:1)

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

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

让我们探索这些文件:

1。 mongo_sample.schema.json

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

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

2。 mongoclass_template.jinja:

这是Mongo类的Jinja模板,该模板最终将用于呈现所需的Python Mongo类。它使用Jinja模板语言。这是Template Designer Documentation的参考。在这里,我们要做的就是创建一个模板,该模板涵盖所有“类型”用例以及“必需”和“正则表达式”之类的参数。请注意,一致的架构很重要:

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模式进行解析,以获取properties对象,将必要的变量传递给模板render()方法,该方法将在渲染模板时使用,最后写入名为{{1 }},这是Mongo的最后一堂课:

models.py

现在,让我们运行此脚本:

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 的新Python脚本将出现在项目文件夹中,内容如下:

models.py