如何在 Flask sqlalchemy 中获取与外键链接的模型属性?
How to get model attribute linked with foreign key in Flask sqlalchemy?
我在 Flask-Sqlalchemy 中创建了两个模型。这些模型是 Tickets
和 Namespace
。两种模型都与外键连接。我还创建了 marshmallow-sqlalchemy ModelSchema
定义以在 RESTful API.
中使用
class Ticket(db.Model):
id = db.Column(db.Integer, primary_key=True)
namespace = db.Column(
db.Integer, db.ForeignKey('namespace.id'), nullable=False)
title = db.Column(db.String)
description = db.Column(db.Text)
status = db.Column(db.String)
severity = db.Column(db.String)
class TicketSchema(ma.ModelSchema):
class Meta:
model = Ticket
include_fk = True
class Namespace(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
class NamespaceSchema(ma.ModelSchema):
class Meta:
model = Namespace
在我看来,我正在尝试通过给定的 命名空间 过滤所有票证。这是我的查询:
@app.route("/<string:name>", methods=["GET"])
def get_tickets_by_namespace(name):
tickets_query = Ticket.query.join(Namespace).filter(Namespace.name == name)
result = TicketSchema(many=True).dump(tickets_query).data
return jsonify({"tickets": result})
如何在连接和过滤两个模型时从 Namespace
模型访问 name
属性?
当我使用 /aa
输入上面的 URL 时,我只得到 namespace_id
,我还想看到命名空间的名称:
{
"tickets": [
{
"description": "xcv",
"id": 1,
"namespace": 1,
"severity": "xcvbn",
"status": "xcvb",
"title": "xc"
},
{
"description": "xcv",
"id": 3,
"namespace": 1,
"severity": "xcvbnb",
"status": "axcvb",
"title": "axcb"
},
{
"description": "xcv",
"id": 4,
"namespace": 1,
"severity": "bnb",
"status": "axcvb",
"title": "aaaxcb"
}
]
}
而不是使用 include_fk
,你想给你的模型一个 relationship:
class Ticket(db.Model):
id = db.Column(db.Integer, primary_key=True)
namespace_id = db.Column(
'namespace',
db.Integer,
db.ForeignKey('namespace.id'),
nullable=False
)
namespace = db.relationship("Namespace", backref="tickets")
title = db.Column(db.String)
description = db.Column(db.Text)
status = db.Column(db.String)
severity = db.Column(db.String)
自动包含关系,但它们的默认字段仍然只序列化外键。
确保只定义 marshmallow-sqlalchemy 模型 在 所有 SQLAlchemy 模型加载后,因为创建模型将触发映射配置 运行 (其中字符串db.relationship()
调用中的 "Namespace"
字符串等表达式)被解析。在 Namespace
模型也已创建之前,您无法创建 Ticket
模型的 Marshmallow 模型。
接下来,use a Nested()
field 拉入您想要的 Namespace
属性:
class TicketSchema(ma.ModelSchema):
class Meta:
model = Ticket
# don't include 'tickets' when including a namespace schema.
# you can also put this on the NestedSchema model.
namespace = ma.Nested("NamespaceSchema", exclude=("tickets",))
在上面的例子中,需要 exclude=("tickets",)
参数来避免 Namespace
对象上的 tickets
关系也反映在结果 JSON 中(它' ll 只包含外键,Marshmallow 意识到它已经序列化了票证)。您还可以将 exclude
添加到 NamespaceSchema
模型 Meta
,但随后 all 使用该架构将排除 tickets
字段.
通过上述更改,您的路由输出:
{
"tickets": [
{
"description": "xcv",
"id": 1,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "xcvbn",
"status": "xcvb",
"title": "xc"
},
{
"description": "xcv",
"id": 3,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "xcvbnb",
"status": "axcvb",
"title": "axcb"
},
{
"description": "xcv",
"id": 4,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "bnb",
"status": "axcvb",
"title": "aaaxcb"
}
]
}
我在 Flask-Sqlalchemy 中创建了两个模型。这些模型是 Tickets
和 Namespace
。两种模型都与外键连接。我还创建了 marshmallow-sqlalchemy ModelSchema
定义以在 RESTful API.
class Ticket(db.Model):
id = db.Column(db.Integer, primary_key=True)
namespace = db.Column(
db.Integer, db.ForeignKey('namespace.id'), nullable=False)
title = db.Column(db.String)
description = db.Column(db.Text)
status = db.Column(db.String)
severity = db.Column(db.String)
class TicketSchema(ma.ModelSchema):
class Meta:
model = Ticket
include_fk = True
class Namespace(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
class NamespaceSchema(ma.ModelSchema):
class Meta:
model = Namespace
在我看来,我正在尝试通过给定的 命名空间 过滤所有票证。这是我的查询:
@app.route("/<string:name>", methods=["GET"])
def get_tickets_by_namespace(name):
tickets_query = Ticket.query.join(Namespace).filter(Namespace.name == name)
result = TicketSchema(many=True).dump(tickets_query).data
return jsonify({"tickets": result})
如何在连接和过滤两个模型时从 Namespace
模型访问 name
属性?
当我使用 /aa
输入上面的 URL 时,我只得到 namespace_id
,我还想看到命名空间的名称:
{
"tickets": [
{
"description": "xcv",
"id": 1,
"namespace": 1,
"severity": "xcvbn",
"status": "xcvb",
"title": "xc"
},
{
"description": "xcv",
"id": 3,
"namespace": 1,
"severity": "xcvbnb",
"status": "axcvb",
"title": "axcb"
},
{
"description": "xcv",
"id": 4,
"namespace": 1,
"severity": "bnb",
"status": "axcvb",
"title": "aaaxcb"
}
]
}
而不是使用 include_fk
,你想给你的模型一个 relationship:
class Ticket(db.Model):
id = db.Column(db.Integer, primary_key=True)
namespace_id = db.Column(
'namespace',
db.Integer,
db.ForeignKey('namespace.id'),
nullable=False
)
namespace = db.relationship("Namespace", backref="tickets")
title = db.Column(db.String)
description = db.Column(db.Text)
status = db.Column(db.String)
severity = db.Column(db.String)
自动包含关系,但它们的默认字段仍然只序列化外键。
确保只定义 marshmallow-sqlalchemy 模型 在 所有 SQLAlchemy 模型加载后,因为创建模型将触发映射配置 运行 (其中字符串db.relationship()
调用中的 "Namespace"
字符串等表达式)被解析。在 Namespace
模型也已创建之前,您无法创建 Ticket
模型的 Marshmallow 模型。
接下来,use a Nested()
field 拉入您想要的 Namespace
属性:
class TicketSchema(ma.ModelSchema):
class Meta:
model = Ticket
# don't include 'tickets' when including a namespace schema.
# you can also put this on the NestedSchema model.
namespace = ma.Nested("NamespaceSchema", exclude=("tickets",))
在上面的例子中,需要 exclude=("tickets",)
参数来避免 Namespace
对象上的 tickets
关系也反映在结果 JSON 中(它' ll 只包含外键,Marshmallow 意识到它已经序列化了票证)。您还可以将 exclude
添加到 NamespaceSchema
模型 Meta
,但随后 all 使用该架构将排除 tickets
字段.
通过上述更改,您的路由输出:
{
"tickets": [
{
"description": "xcv",
"id": 1,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "xcvbn",
"status": "xcvb",
"title": "xc"
},
{
"description": "xcv",
"id": 3,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "xcvbnb",
"status": "axcvb",
"title": "axcb"
},
{
"description": "xcv",
"id": 4,
"namespace": {
"id": 1,
"name": "aa"
},
"severity": "bnb",
"status": "axcvb",
"title": "aaaxcb"
}
]
}