python - 使用嵌套字段加载/反序列化对象
问题描述
我有两个sqlalchemy
模型 -ServiceRecord
和Service
,有一个many-to-many
关系,它是通过一个service_record_services
表来解决的。我正在尝试ServiceRecord
从以下 JSON 反序列化对象,并通过提供Service
的从 db 加载对象。ids
相反,我最终Service
创建了新对象。
# from POST
{'service_date': '08/21/2019 08:00 pm', 'site_id': 33, 'subcontractor_id': 37, 'services': [{'id':1},{'id': 2}]}
楷模:
class Service(db.Model):
__tablename__ = 'services'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True)
comments = db.Column(db.String(200), nullable=True, unique=False)
class ServiceRecord(db.Model):
__tablename__ = 'service_records'
id = db.Column(db.Integer, primary_key=True)
created = db.Column(db.DateTime, server_default=db.func.now())
datetime = db.Column(db.DateTime)
subcontractor_id = db.Column(db.Integer, db.ForeignKey('subcontractors.id'))
subcontractor = db.relationship( 'Subcontractor', back_populates='service_records')
site_id = db.Column(db.Integer, db.ForeignKey('sites.id'))
site = db.relationship('Site', back_populates='service_records')
# all services for this record
services = db.relationship('Service', secondary=lambda: service_record_services)
架构:
class ServiceSchema(ma.ModelSchema):
class Meta:
include_fk = True
model = models.Service
strict = False
sqla_session = db.session
transient = True
name = fields.Str(dump_only=True)
class ServiceRecordSchema(ma.ModelSchema):
class Meta:
include_fk = True
model = models.ServiceRecord
sqla_session = db.session
id = fields.Int(dump_only=True)
subcontractor_name = fields.Function(lambda obj: obj.subcontractor.name, dump_only=True)
site_name = fields.Function(lambda obj: obj.site.name, dump_only=True)
services = fields.Nested(ServiceSchema, many=True)
service_date = fields.DateTime(format='%m/%d/%Y %I:%M %p', attribute='datetime')
@pre_load
def process_services(self, data):
current_app.logger.debug('[pre_load - 1] data: {}'.format(data))
service_ids = map(lambda x: x.get('id'), data.get('services'))
services = models.Service.query.filter(models.Service.id.in_(service_ids)).all()
# i'd like to be able to use these Service objects in the loaded ServiceRecord
data['_services'] = services
return data
DEBUG in schema: [pre_load - 1] data: {'service_date': '08/21/2019 08:00 pm', 'site_id': 33, 'subcontractor_id': 37, 'services': [{'id': 1}, {'id': 2}]}
DEBUG in schema: service_ids: [1, 2]
DEBUG in resource: resource: <class 'app.models.ServiceRecord'>(site_id:33, subcontractor_id:37, datetime:2019-08-21 20:00:00)
DEBUG in resource: resource services: [<Service(name=None)>, <Service(name=None)>]
解决方案
事实证明,我所要做的就是将两个必填字段添加到我的 ServiceSchema,删除transient=True
,就是这样。这是工作代码:
class ServiceSchema(ma.ModelSchema):
class Meta:
include_fk = True
model = models.Service
strict = False
sqla_session = db.session
id = fields.Int()
name = fields.Str()
class ServiceRecordSchema(ma.ModelSchema):
class Meta:
include_fk = True
model = models.ServiceRecord
sqla_session = db.session
id = fields.Int(dump_only=True)
subcontractor_name = fields.Function(lambda obj: obj.subcontractor.name, dump_only=True)
site_name = fields.Function(lambda obj: obj.site.name, dump_only=True)
service_date = fields.DateTime(format='%m/%d/%Y %I:%M %p', attribute='datetime')
services = fields.Nested(ServiceSchema, many=True)
推荐阅读
- python - 共享层,不同模型
- javascript - 当父级太小时防止div包装
- python - 使用 python selenium 在文本框中输入值
- javascript - JavaScript 在布局中找不到元素
- react-native - React Native Redux - 从预填充数据中分配状态属性
- cordova - Visual Studio 2017 Cordova App 项目系统遇到错误
- sql - SQL:将插入更改为查询以适应不同列的输入表
- java - Spring Boot 条件调度
- codenameone - 表单加载后如何刷新表单
- rest - Scala:验证控制器中的 Restful 参数