#python #json #mongodb #model #yaml
#python #json #mongodb #Модель #yaml
Вопрос:
Я пробую MongoEngine, библиотеку DRM для Python для использования с MongoDB. Я могу определить модель, подобную этому примеру, с сайта:
class User(Document):
email = StringField(required=True)
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
Это работает как шарм, и MongoEngine действительно хорош. Что ж, я хочу пойти дальше и задаться вопросом, могу ли я определить свои модели где-нибудь в файле в формате JSON или YAML, или что-то еще, чтобы затем создать модель, используя ее. Таким образом, это объявление могло бы выглядеть следующим образом в JSON:
{
"model":"User",
"fields":{
"email":{
"type":"string",
"required":"true"
},
"first_name":{
"type":"string",
"max_length":"50"
},
"last_name":{
"type":"string",
"max_length":"50"
}
}
}
Затем я бы проанализировал этот JSON и создал модель, используя его. Может быть, это могла бы быть всего лишь одна операция импорта, которую я выполнял бы каждый раз, когда изменяю определение модели, или, может быть, он мог бы анализировать весь JSON каждый раз. Это хороший сценарий? Я просто хочу позволить людям, которые будут использовать приложение, определять свои собственные модели без необходимости копаться в коде. Приветствуются любые идеи о том, как создать динамическую модель
Ответ №1:
Если вы собираетесь использовать YAML, pyyaml совершенно безболезнен и автоматически выводит структуру данных, используя встроенные типы python (или даже более сложные типы, которые вы определяете).
В любом случае, я бы также настоятельно рекомендовал Rx в качестве средства проверки, чтобы вы могли легко проверить целостность загруженных файлов.*
Что касается использования этого для создания модели, вы можете использовать встроенную функцию type
(не type(object)
, но type(name, bases, dict)
), которая… «[r] создайте объект нового типа. По сути, это динамическая форма инструкции класса.»
Итак, вы можете вызвать:
def massage(fields_dict):
#transform your file format into a valid set of fields, and return it
user_class = type(yaml_data['model'], Document, massage(yaml_data['fields']) )
* По совпадению, я использовал оба из них вместе в течение последних восьми часов — они безболезненно работают вместе, например:
import yaml
import Rx
data = yaml.load(open("foo.yaml")
rx = Rx.Factory({ "register_core_types": True })
schema = rx.make_schema(yaml.load(open("schema.yaml")))
if not schema.check(data):
raise ValueError("data file contents are not in a valid format")