【问题标题】:Many-to-many relation insert record in FlaskFlask中的多对多关系插入记录
【发布时间】:2021-07-12 03:54:07
【问题描述】:

使用 ma​​rshmallow@3.11.1Flask@1.1.2Flask-SQLAlchemy@2.4.4 和 SQLAlchemy @1.3.23 我正在尝试在数据库中存储新数据。

我在使用一对多关系创建没有任何关系的记录时没有任何问题,但我正在努力创建一个具有多对多关系的新记录。

我有职位,可能有不同的类型。要建立多对多关系,我使用关联表:

class PositionsModel(db.Model):

  __tablename__ = "positions"

  id = db.Column(db.Integer, primary_key=True)
  position_name = db.Column(db.String(150), nullable=False)

  types_of_work = db.relationship(
    "TypesOfWorkModel",
    secondary=positions_types_of_work,
    lazy="joined",
    backref=db.backref("type_positions", lazy="noload")
  )

def __init__(self, data):
    self.position_name = data.get("position_name")
    self.types_of_work = data.get("types_of_work", [])
  
  def create(self):
    db.session.add(self)
    db.session.commit()

class TypesOfWorkModel(db.Model):

  __tablename__ = "types_of_work"

  id = db.Column(db.Integer, primary_key=True)
  work_type_name = db.Column(db.String(150), nullable=False)


positions_types_of_work = db.Table(
  "positions_types_of_work",
  db.Column("position_id", db.Integer, db.ForeignKey("positions.id"), primary_key=True),
  db.Column("type_of_work_id", db.Integer, 
            db.ForeignKey("types_of_work.id"), primary_key=True)
)

我还有一个用于创建记录时使用的所有其他表的架构。这是我创建新职位的架构:

class PositionsModelSchemaCreate(Schema):

  id = fields.Int()
  position_name = fields.Str(required=True)
  types_of_work = fields.List(
    fields.Int,
    validate=validate_types_of_work
  )

  @post_load
  def attach_models(self, data, **kwargs):
    # query to get actual model records for "types_of_work"
    return data

那么当请求创建新职位时会发生什么?

  """
    request data looks like this:
    {
      "position_name": "Test",
      "types_of_work": [1, 2]
    }
  """
  req_data = request.get_json()
  data = positions_schema_create.load(req_data)

这段代码根据模式加载数据,调用验证函数。在 types_of_work 的情况下,它只检查请求正文中的 ID 是数据库中现有记录的 ID。

然后它到达 @post_load 装饰器,它将 types_of_work 的 ID 替换为这些类型的实际数据库记录。

最终,我的请求数据将如下所示:

{
  'position_name': 'Pos Name Test',
  'types_of_work': [<TypesOfWork One>, <TypesOfWork Two>]
}

我用于创作:

  position = PositionsModel(data)
  position.create()

它返回一个错误:

int() argument must be a string, a bytes-like object or a number, not 'TypesOfWorkModel'

我阅读了一些其他帖子 herehere,看起来我正在做相应的事情,但仍然有错误。

任何建议将不胜感激!

【问题讨论】:

  • 为什么你的关联表中有, primary_key=True,我认为这不是必需的,而且在你分享的两个例子中都没有
  • @RolvApneseth 嗯,是的,你是对的,删除了那个,但同样的错误仍然存​​在
  • 是的,我认为它不会,无论如何我已经对你的问题投了赞成票,希望对此有更多了解的人可以提供帮助

标签: python flask sqlalchemy flask-sqlalchemy marshmallow


【解决方案1】:

应该是

position = PositionsModel(**data)
position.create()

如果在@post_load 中返回 json/dict

【讨论】:

    猜你喜欢
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    相关资源
    最近更新 更多