【问题标题】:How to get model attribute linked with foreign key in Flask sqlalchemy?如何在 Flask sqlalchemy 中获取与外键链接的模型属性?
【发布时间】:2019-11-10 14:28:37
【问题描述】:

我在 Flask-Sqlalchemy 中创建了两个模型。这些模型是TicketsNamespace。两种模型都使用外键连接。我还创建了 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"
    }
  ]
}

【问题讨论】:

  • don' use images of code, data or errors。将它们发布为 text,以便我们可以尝试重现问题而无需重新输入所有内容,并且屏幕阅读器可以正确索引或阅读您的问题。
  • 清除,谢谢,对这个问题深表歉意。

标签: python flask sqlalchemy flask-sqlalchemy marshmallow


【解决方案1】:

你想给你的模型一个relationship而不是include_fk

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) 

自动包含关系,但它们的默认字段仍然只序列化外键。

确保只定义棉花糖-sqlalchemy 模型所有你的 SQLAlchemy 模型已经加载,因为创建模型将触发映射配置运行(其中字符串表达式,如 "Namespace" 中的字符串987654326@ call) 已解决。在创建 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 中(它将仅包含外键,Marshmallow 意识到它已经序列化了票)。您还可以将exclude 添加到NamespaceSchema 模型Meta,但是所有使用该架构将排除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"
    }
  ]
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2020-09-23
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多