我正在寻找一种方法来获取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$")