如何在使用 Marshmallow 加入后序列化 SQL 数据? (烧瓶延伸)
How to Serialize SQL data after a Join using Marshmallow? (flask extension)
我在 SQL 中有 2 个 table:
class Zoo(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(80), unique=True, nullable=False)
idade = db.Column(db.Integer, unique=False, nullable=False)
peso = db.Column(db.Float, unique=False, nullable=False)
cuidador = db.Column(db.Integer, db.ForeignKey('cuidador.id'))
class Cuidador(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(80), unique=True, nullable=False)
animais = db.relationship('Zoo', backref='zoo', lazy=True)
并且架构定义:
class WorkerSchema(ma.SQLAlchemySchema):
class Meta:
model = Cuidador
id = ma.auto_field()
nome = ma.auto_field()
class ZooSchema(ma.SQLAlchemySchema):
class Meta:
model = Zoo
id = ma.auto_field()
nome = ma.auto_field()
idade = ma.auto_field()
peso = ma.auto_field()
cuidador = ma.Nested(WorkerSchema)
在可视化路线中,我定义了以下函数来可视化 Zoo table 中存在的数据:
def see_all_animals(self):
result_join = db.session.query(Zoo,Cuidador).join(Zoo).all()
zoo_schema = ZooSchema()
result = zoo_schema.dump(result_join,many=True)
return result
不幸的是函数returns完全清空了数据。我希望在这些方面出现一些东西:
{
...."id": 3,
...."idade": 5,
...."nome": "Cabra",
...."peso": 12.0,
...."cuidador": {"id":1,"nome":"Juan"}
}
你的例子中使用的数据库关系的反向引用为Zoo
类型的对象添加了一个zoo
属性,在该属性下可以查询引用的Cuidador
对象。
对于目前使用的数据库建模,我推荐以下棉花糖模式。这涉及将数据库关系定义的反向引用从“zoo”重命名为“cuidador”。
class WorkerSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Cuidador
class ZooSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Zoo
cuidador = ma.Nested(WorkerSchema, attribute='zoo')
不需要主动使用连接语句来实现所需的输出。由于定义的关系和嵌套架构,引用数据的查询和格式化会自动进行。
def index():
zoos = Zoo.query.all()
zoos_schema = ZooSchema(many=True)
zoos_data = zoos_schema.dump(zoos)
return jsonify(data=zoos_data)
这里获得的输出现在如下。
{
"data": [
{
"cuidador": {
"id": 1,
"nome": "Juan"
},
"id": 1,
"idade": 5,
"nome": "Cabra",
"peso": 12.0
}
]
}
建议大家在建模的时候多注意命名,避免不必要的重命名,加深对数据库关系的认识。关系的正确表示和命名中避免重复将帮助您完成更大更大的项目,祝您玩得开心。
我在 SQL 中有 2 个 table:
class Zoo(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(80), unique=True, nullable=False)
idade = db.Column(db.Integer, unique=False, nullable=False)
peso = db.Column(db.Float, unique=False, nullable=False)
cuidador = db.Column(db.Integer, db.ForeignKey('cuidador.id'))
class Cuidador(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(80), unique=True, nullable=False)
animais = db.relationship('Zoo', backref='zoo', lazy=True)
并且架构定义:
class WorkerSchema(ma.SQLAlchemySchema):
class Meta:
model = Cuidador
id = ma.auto_field()
nome = ma.auto_field()
class ZooSchema(ma.SQLAlchemySchema):
class Meta:
model = Zoo
id = ma.auto_field()
nome = ma.auto_field()
idade = ma.auto_field()
peso = ma.auto_field()
cuidador = ma.Nested(WorkerSchema)
在可视化路线中,我定义了以下函数来可视化 Zoo table 中存在的数据:
def see_all_animals(self):
result_join = db.session.query(Zoo,Cuidador).join(Zoo).all()
zoo_schema = ZooSchema()
result = zoo_schema.dump(result_join,many=True)
return result
不幸的是函数returns完全清空了数据。我希望在这些方面出现一些东西:
{
...."id": 3,
...."idade": 5,
...."nome": "Cabra",
...."peso": 12.0,
...."cuidador": {"id":1,"nome":"Juan"}
}
你的例子中使用的数据库关系的反向引用为Zoo
类型的对象添加了一个zoo
属性,在该属性下可以查询引用的Cuidador
对象。
对于目前使用的数据库建模,我推荐以下棉花糖模式。这涉及将数据库关系定义的反向引用从“zoo”重命名为“cuidador”。
class WorkerSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Cuidador
class ZooSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Zoo
cuidador = ma.Nested(WorkerSchema, attribute='zoo')
不需要主动使用连接语句来实现所需的输出。由于定义的关系和嵌套架构,引用数据的查询和格式化会自动进行。
def index():
zoos = Zoo.query.all()
zoos_schema = ZooSchema(many=True)
zoos_data = zoos_schema.dump(zoos)
return jsonify(data=zoos_data)
这里获得的输出现在如下。
{
"data": [
{
"cuidador": {
"id": 1,
"nome": "Juan"
},
"id": 1,
"idade": 5,
"nome": "Cabra",
"peso": 12.0
}
]
}
建议大家在建模的时候多注意命名,避免不必要的重命名,加深对数据库关系的认识。关系的正确表示和命名中避免重复将帮助您完成更大更大的项目,祝您玩得开心。