Проблема
Как сгруппировать поля вместе при сериализации объекта SQLAlchemy с плоской структурой с помощью Marshmallow без изменения плоской структуры данных в фоновом режиме?
Пример
Предположим, что модель SQLAlchemy в приложении Flask выглядит следующим образом:
из базы данных импорта приложения # db с использованием SQLAlchemy Данные класса (db.Model): x = db.Column(db.Float(), требуется=True) y = db.Column(db.Float(), требуется=True) d = db.Column(db.Float()) Как я могу сериализовать этот объект, чтобы x и y были вложены в координаты, сохраняя при этом плоскую структуру данных в фоновом режиме ( модель)? Результат должен выглядеть примерно так:
{ "координаты": { «х»: 10,56 "й": 1 }, «д»: 42,0 } Проблема возникает именно потому, что я использую схему Data с опцией many=True. Инициализация примерно такая:
schema_data = MomentData() Schema_datas = MomentData (многие = True) Кандидаты на решение Итак, вот что я пробовал до сих пор, но ничего из этого не сработало.
Создание второй схемы
Добавление второй схемы и изменение схемы Data из предыдущей схемы:
класс КоординатыSchema(Схема): x = поля.Float(обязательно=True) y = поля.Float(обязательно=True) класс DataSchema(Схема): координаты = поля.Вложенные(координатыСхема, требуется=Истина) d = поля.Float() При этом возникает проблема, связанная с необходимостью просматривать каждый элемент Data и вручную добавлять схему Coordinates. Мои данные поступают из запроса SQLAlchemy, возвращающего список объектов Data, поэтому я могу легко сбросить их с помощью schema_datas.
Использование fields.Dict
Поскольку модуль Marshmallows fields предлагает словарь, я тоже попробовал это.
защита DataSchema (Схема): координаты = поля.Dict(keys=fields.String(), значение = поля.Float(), требуется = Истина, по умолчанию={ «х»: Данные.х, "y": Данные.y }) d = поля.Float() Похоже, это тоже не работает, потому что Marshmallow не может автоматически найти Data.x и Data.y при использовании schema_datas.dump()< /код>.
Использование самостоятельного вложения
Наиболее логичным решением будет самостоятельное вложение. Но (насколько я понял, прочитав документацию) самовложение относится только к вложению одного или нескольких экземпляров other внутри объекта. Я хочу вложить один и тот же экземпляр.
класс DataSchema(Схема): x = поля.Float(обязательно=True, load_only=True) y = поля.Float(обязательно=True, load_only=True) координаты = поля.Вложенные( лямбда: DataSchema(only=('x', 'y')), dump_only=Истина) Но, к сожалению, и это не сработало.
Использование декоратора @pre_dump
Вдохновленный этой проблемой на странице Marshmallow на Github, я попытался использовать декоратор @pre_dump для достижения желаемого результата, но снова потерпел неудачу.
класс КоординатыSchema(Схема): x = поля.Float(обязательно=True) y = поля.Float(обязательно=True) класс DataSchema(Схема): координаты = поля.Вложенные(координатыСхема, требуется=Истина) d = поля.Float() @pre_dump def group_coordinates(сам, данные, многие): возвращаться { "координаты": { «х»: данные.х, «у»: данные.у }, "д": data.d } Но я не могу понять, как это сделать правильно...
Итак, мой вопрос: что я делаю не так и как мне решить эту проблему?